All files / src/libs/DependencyInjection/decorators RegisterInstance.ts

37.5% Statements 6/16
0% Branches 0/4
50% Functions 2/4
37.5% Lines 6/16

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 712x                                     2x                 2x   2x     2x                                                                   2x      
import { DIContainer } from '../DIContainer';
import { InitDelegate } from '../types/InitDelegate';
 
/**
 * A decorator to register an instance of a class in the DI (Dependency Injection) container.
 * The instance is created only when it is first needed (Lazy Initialization).
 * @template TargetType The type of the class whose instance is to be registered.
 * @param identifier The identifier used to register the instance in the DI container.
 * @param init An optional initializer function which get the constructor of the class
 * as input and returns an instance of the class.
 * @returns A function that is applied as a decorator to the class.
 * @example
 * ```ts
 * \@RegisterInstance('MyClassInstanceIdentifier', arg1, arg2)
 * class MyClass {
 *   // ...
 * }
 * ```
 */
export function RegisterInstance<
    TargetType extends new (..._args: unknown[]) => InstanceType<TargetType>,
>(
    identifier: string,
    init?: InitDelegate<
        TargetType & { new (..._args: unknown[]): InstanceType<TargetType> },
        InstanceType<TargetType>
    >,
) {
    return function (constructor: TargetType, ...args: unknown[]): void {
        // Get the instance of the DI container
        const diContainer = DIContainer.getInstance();
 
        // Create a proxy to instantiate the class when needed (Lazy Initialization)
        let lazyProxy: unknown = new Proxy(
            {},
            {
                get(target, prop, receiver) {
                    let instance: InstanceType<TargetType>;
 
                    if (init) {
                        instance = init(constructor);
                    } else {
                        instance = new constructor(...args);
                    }
                    lazyProxy = instance;
 
                    // Return the requested property of the instance
                    return instance[prop as keyof InstanceType<TargetType>];
                },
                set(target, prop, value, receiver) {
                    let instance: InstanceType<TargetType>;
 
                    if (init) {
                        instance = init(constructor);
                    } else {
                        instance = new constructor(...args);
                    }
                    lazyProxy = instance;
 
                    // Set the requested property of the instance
                    return (instance[prop as keyof InstanceType<TargetType>] =
                        value);
                },
            },
        );
 
        // Register the lazy proxy in the DI container
        diContainer.register(identifier, lazyProxy);
    };
}
 
Zur TypeDoc-Dokumentation