Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | 7x 7x 23x 23x 23x 23x 190x 23x 411x 190x 54x 54x 14x 136x 411x | import { DIContainer } from '../DIContainer'; import { InitDelegate } from '../types/InitDelegate'; /** * A decorator to inject a dependency from a DI (Dependency Injection) container. * The dependency is lazily evaluated when the property is accessed for the first time. * This can help avoid issues like circular dependencies and not-found dependencies. * @template ClassType The type of the property to be injected. * @param identifier The identifier used to resolve the dependency from the DI container. * @param init An optional initializer function to transform the dependency before injection. * @param necessary Indicates if the dependency is necessary. * - If `true`, an error will be thrown if the dependency cannot be resolved. * - If `false`, `undefined` will be returned if the dependency cannot be resolved. * @returns A decorator function to be applied on the class property. * @see {@link DIContainer} * @example * ```ts * class MyClass { * \@Inject<MyDependency>('MyDependencyIdentifier') * private myDependency!: MyDependency; * } * ``` * @example * ```ts * class MyClass { * \@Inject('ILogger_', (x: ILogger_) => x.getLogger('Tags'), false) * private _logger?: ILogger; * } * ``` */ export function Inject<T, U>( identifier: string, init?: InitDelegate<T, U>, necessary = true, ) { return function (target: unknown, propertyKey: string | symbol): void { // Unique symbol to store the private property const privatePropertyKey: unique symbol = Symbol(); // Get the DI container instance const diContainer = DIContainer.getInstance(); // Function to evaluate the dependency lazily // to avoid circular dependencies, not found dependencies, etc. const evaluate = (): T | undefined => { return diContainer.resolve<T>(identifier, necessary); }; // Define the property Object.defineProperty(target, propertyKey, { get() { // If the property is not defined, evaluate the dependency if (!this.hasOwnProperty(privatePropertyKey)) { if (init) { try { this[privatePropertyKey] = init(evaluate() as T); } catch (error) { Iif (necessary) { throw error; } } } else { this[privatePropertyKey] = evaluate(); } } return this[privatePropertyKey]; }, // Not necessary to set the property // set(value: PropertieType) { // this[privatePropertyKey] = value; // }, enumerable: true, configurable: false, }); }; } |