@elsikora/cladi
Version:
ClaDI is a library for creating and managing classes in TypeScript.
195 lines (191 loc) • 8.24 kB
JavaScript
;
var error_class = require('./error.class.js');
var consoleLogger_service = require('../../service/console-logger.service.js');
/**
* Simple dependency injection container implementation.
* @see {@link https://elsikora.com/docs/cladi/core-concepts/container}
*/
class BaseContainer {
DEPENDENCIES;
LOGGER;
/**
* Create a new container.
* @param {IBaseContainerOptions} options - The options to use for the container.
*/
constructor(options) {
this.DEPENDENCIES = new Map();
this.LOGGER = options.logger ?? new consoleLogger_service.ConsoleLoggerService();
}
/**
* Clear all dependencies from the container.
*/
clear() {
this.LOGGER.debug("Clearing all dependencies from container", { source: "Container" });
this.DEPENDENCIES.clear();
this.LOGGER.debug("Container cleared successfully", { source: "Container" });
}
/**
* Get a dependency from the container.
* @param {symbol} token Token that identifies the dependency.
* @returns {T | undefined} The dependency, or undefined if it doesn't exist.
* @template T The type of the dependency.
*/
// eslint-disable-next-line @elsikora/typescript/no-unnecessary-type-parameters
get(token) {
if (!token) {
this.LOGGER.warn("Attempted to get dependency with empty token", { source: "Container" });
return undefined;
}
this.LOGGER.debug(`Getting dependency with token: ${String(token.description)}`, { source: "Container" });
const dependency = this.DEPENDENCIES.get(token);
if (dependency) {
this.LOGGER.debug(`Dependency found: ${String(token.description)}`, { source: "Container" });
}
else {
this.LOGGER.debug(`Dependency not found: ${String(token.description)}`, { source: "Container" });
}
return dependency;
}
/**
* Get all dependencies from the container.
* @returns {Array<unknown>} An array of all dependencies.
*/
getAll() {
this.LOGGER.debug("Getting all dependencies", { source: "Container" });
const dependencies = [...this.DEPENDENCIES.values()];
this.LOGGER.debug(`Retrieved ${String(dependencies.length)} dependencies`, { source: "Container" });
return dependencies;
}
/**
* Get multiple dependencies from the container.
* @param {Array<symbol>} tokens Tokens that identify the dependencies.
* @returns {Array<unknown>} An array of dependencies.
*/
getMany(tokens) {
if (!tokens) {
throw new error_class.BaseError("Tokens cannot be null or undefined", {
code: "CONTAINER_TOKENS_NOT_NULL_OR_UNDEFINED",
source: "Container",
});
}
if (!Array.isArray(tokens)) {
throw new error_class.BaseError("Tokens must be an array", {
code: "CONTAINER_TOKENS_NOT_ARRAY",
source: "Container",
});
}
this.LOGGER.debug(`Getting ${String(tokens.length)} dependencies by token`, { source: "Container" });
const result = tokens.map((token) => this.get(token)).filter((item) => item !== undefined);
this.LOGGER.debug(`Retrieved ${String(result.length)} dependencies`, { source: "Container" });
return result;
}
/**
* Check if a dependency exists in the container.
* @param {symbol} token Token that identifies the dependency.
* @returns {boolean} True if the dependency exists, false otherwise.
*/
has(token) {
if (!token) {
return false;
}
this.LOGGER.debug(`Checking if dependency exists: ${String(token.description)}`, { source: "Container" });
const isExists = this.DEPENDENCIES.has(token);
this.LOGGER.debug(`Dependency ${isExists ? "exists" : "does not exist"}: ${String(token.description)}`, { source: "Container" });
return isExists;
}
/**
* Register a dependency in the container.
* @param {symbol} token Token that identifies the dependency.
* @param {T} implementation Implementation of the dependency.
* @template T The type of the dependency.
*/
register(token, implementation) {
if (!token) {
throw new error_class.BaseError("Token cannot be null or undefined", {
code: "CONTAINER_TOKEN_NOT_NULL_OR_UNDEFINED",
source: "Container",
});
}
this.LOGGER.debug(`Registering dependency with token: ${String(token.description)}`, { source: "Container" });
if (this.has(token)) {
throw new error_class.BaseError("Dependency already exists in container", {
code: "CONTAINER_DEPENDENCY_ALREADY_EXISTS",
source: "Container",
});
}
this.DEPENDENCIES.set(token, implementation);
this.LOGGER.debug(`Dependency registered successfully: ${String(token.description)}`, { source: "Container" });
}
/**
* Register multiple dependencies in the container.
* @param {Array<symbol>} tokens Tokens that identify the dependencies.
* @param {Array<T>} implementations Implementations of the dependencies.
* @template T The type of the dependencies.
*/
registerMany(tokens, implementations) {
if (!tokens) {
throw new error_class.BaseError("Tokens cannot be null or undefined", {
code: "CONTAINER_TOKENS_NOT_NULL_OR_UNDEFINED",
source: "Container",
});
}
if (!Array.isArray(tokens)) {
throw new error_class.BaseError("Tokens must be an array", {
code: "CONTAINER_TOKENS_NOT_ARRAY",
source: "Container",
});
}
this.LOGGER.debug(`Registering ${String(tokens.length)} dependencies`, { source: "Container" });
// eslint-disable-next-line @elsikora/no-secrets/no-pattern-match
for (const token of tokens) {
this.register(token, implementations[token]);
}
this.LOGGER.debug(`${String(tokens.length)} dependencies registered successfully`, { source: "Container" });
}
/**
* Remove a dependency from the container.
* @param {symbol} token Token that identifies the dependency.
*/
unregister(token) {
if (!token) {
throw new error_class.BaseError("Token cannot be null or undefined", {
code: "CONTAINER_TOKEN_NOT_NULL_OR_UNDEFINED",
source: "Container",
});
}
this.LOGGER.debug(`Unregistering dependency with token: ${String(token.description)}`, { source: "Container" });
const wasDeleted = this.DEPENDENCIES.delete(token);
if (wasDeleted) {
this.LOGGER.debug(`Dependency unregistered successfully: ${String(token.description)}`, { source: "Container" });
}
else {
this.LOGGER.debug(`Dependency not found for unregistering: ${String(token.description)}`, { source: "Container" });
}
}
/**
* Remove multiple dependencies from the container.
* @param {Array<symbol>} tokens Tokens that identify the dependencies.
*/
unregisterMany(tokens) {
if (!tokens) {
throw new error_class.BaseError("Tokens cannot be null or undefined", {
code: "CONTAINER_TOKENS_NOT_NULL_OR_UNDEFINED",
source: "Container",
});
}
if (!Array.isArray(tokens)) {
throw new error_class.BaseError("Tokens must be an array", {
code: "CONTAINER_TOKENS_NOT_ARRAY",
source: "Container",
});
}
this.LOGGER.debug(`Unregistering ${String(tokens.length)} dependencies`, { source: "Container" });
// eslint-disable-next-line @elsikora/no-secrets/no-pattern-match
for (const token of tokens) {
this.unregister(token);
}
this.LOGGER.debug(`${String(tokens.length)} dependencies unregistered`, { source: "Container" });
}
}
exports.BaseContainer = BaseContainer;
//# sourceMappingURL=container.class.js.map