import { Descriptor, PartialServiceMap, ILifetime, ContainerKeys } from "../interfaces"; import { ActivationContext } from "../ActivationContext"; import { each } from "../../safe"; import { DependencyOptions, LazyDependencyOptions, Resolver } from "./interfaces"; export interface DescriptorImplArgs { lifetime: ILifetime; factory: (resolve: Resolver) => T; cleanup?: (item: T) => void; overrides?: PartialServiceMap; } export class DescriptorImpl implements Descriptor { private readonly _overrides?: PartialServiceMap; private readonly _lifetime: ILifetime; private readonly _factory: (resolve: Resolver) => T; private readonly _cleanup?: (item: T) => void; constructor(args: DescriptorImplArgs) { this._lifetime = args.lifetime; this._factory = args.factory; if (args.cleanup) this._cleanup = args.cleanup; if (args.overrides) this._overrides = args.overrides; } activate(context: ActivationContext): T { if (this._lifetime.has()) return this._lifetime.get(); this._lifetime.initialize(context); if (this._overrides) each(this._overrides, (v, k) => context.register(k, v)); const resolve = (name: ContainerKeys, opts?: DependencyOptions | LazyDependencyOptions) => { if (opts && "lazy" in opts && opts.lazy) { const c2 = context.clone(); return () => { return opts.optional ? c2.resolve(name, opts.default) : c2.resolve(name); }; } else { return opts && opts.optional ? context.resolve(name, opts.default) : context.resolve(name); } }; const instance = this._factory.call(undefined, resolve); this._lifetime.store(instance, this._cleanup); return instance; } toString() { return `[object DescriptorImpl, lifetime=${this._lifetime}]`; } }