Files
TSinjex/src/classes/TSinjex.ts
Max P 9a4fdecaac Update warning message in TSinjex class
- Converted `identifier` to string in the deprecation warning.
2024-08-23 00:17:14 +02:00

128 lines
3.5 KiB
TypeScript

import type { Inject } from '../decorators/Inject';
import type { Register } from '../decorators/Register';
import type { RegisterInstance } from '../decorators/RegisterInstance';
import type { register } from '../functions/register';
import type { resolve } from '../functions/resolve';
import { ImplementsStatic } from '../helper/ImplementsStatic';
import { DependencyResolutionError } from '../interfaces/Exceptions';
import { IDependency } from '../interfaces/IDependency';
import { ITSinjex, ITSinjex_ } from '../interfaces/ITSinjex';
import { Identifier } from '../types/Identifier';
/**
* # TSinjex
* The main class for the Dependency Injection Container **TSinjex**.
* ### Decorators
* @see {@link Register} for registering a class in the DI container.
* @see {@link RegisterInstance} for registering an instance in the DI container.
* @see {@link Inject} for injecting a dependency into a property.
* ---
* ### Functions
* @see {@link register} for registering a dependency (class or instance) as a function.
* @see {@link resolve} for resolving a dependency as a function.
*/
@ImplementsStatic<ITSinjex_>()
export class TSinjex implements ITSinjex {
/**
* The singleton instance of the TSinjex class.
*/
private static _instance: TSinjex;
/**
* The dependencies map.
*/
private readonly _dependencies = new Map<Identifier, IDependency>();
/**
* Private constructor to prevent direct instantiation.
*/
private constructor() {}
//#region ITSinjex_ (Static)
/**
* Get the **singleton** TSInjex instance.
* @returns The singleton instance.
*/
public static getInstance(): ITSinjex {
if (this._instance == null) {
this._instance = new TSinjex();
}
return this._instance;
}
/**
* Static implementation of {@link ITSinjex.register}.
* @see {@link ITSinjex.register}
* @inheritdoc
*/
public static register<T>(
identifier: Identifier,
dependency: T,
deprecated = false,
): void {
(TSinjex.getInstance() as TSinjex)._dependencies.set(identifier, {
dependency: dependency,
deprecated: deprecated,
});
}
/**
* Static implementation of {@link ITSinjex.resolve}.
* @see {@link ITSinjex.resolve}
* @inheritdoc
*/
public static resolve<T>(
identifier: Identifier,
necessary = true,
): T | undefined {
return (TSinjex.getInstance() as TSinjex).resolve<T>(
identifier,
necessary,
);
}
//#endregion
//#region ITSinjex (Instance)
/**
* @inheritdoc
*/
public register<T>(
identifier: Identifier,
dependency: T,
deprecated = false,
): void {
this._dependencies.set(identifier, {
dependency: dependency,
deprecated: deprecated,
});
}
/**
* @inheritdoc
*/
public resolve<T>(identifier: Identifier, necessary = true): T | undefined {
const dependency = this._dependencies.get(identifier);
if (necessary && !dependency) {
throw new DependencyResolutionError(identifier);
} else if (!dependency) {
return undefined;
}
if (dependency.deprecated) {
console.warn(`Dependency ${identifier.toString()} is deprecated`);
// Remove the deprecation warning; it should only be logged once.
dependency.deprecated = false;
}
return dependency.dependency as T;
}
//#endregion
}