|
|
import { Descriptor, ILifetime, ConfigurableKeys, Resolver } from "./interfaces";
|
|
|
import { ActivationContext } from "./ActivationContext";
|
|
|
import { ContextResolver } from "./ContextResolver";
|
|
|
import { each } from "./traits";
|
|
|
|
|
|
export type RegistrationOverridesMap<S extends object> = { [k in ConfigurableKeys<S>]?: Descriptor<S, NonNullable<S[k]>> };
|
|
|
|
|
|
export interface DescriptorImplArgs<S extends object, T> {
|
|
|
lifetime: ILifetime<T>;
|
|
|
|
|
|
factory: (resolve: Resolver<S>) => T;
|
|
|
|
|
|
cleanup?: (item: T) => void;
|
|
|
|
|
|
overrides?: RegistrationOverridesMap<S>;
|
|
|
}
|
|
|
|
|
|
|
|
|
export class DescriptorImpl<S extends object, T> implements Descriptor<S, T> {
|
|
|
|
|
|
private readonly _overrides?: RegistrationOverridesMap<S>;
|
|
|
|
|
|
private readonly _lifetime: ILifetime<T>;
|
|
|
|
|
|
private readonly _factory: (resolve: Resolver<S>) => T;
|
|
|
|
|
|
private readonly _cleanup?: (item: T) => void;
|
|
|
|
|
|
constructor(args: DescriptorImplArgs<S, T>) {
|
|
|
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<S>): 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 resolver = new ContextResolver(context);
|
|
|
|
|
|
|
|
|
const instance = this._factory.call(undefined, resolver.resolve.bind(resolver));
|
|
|
|
|
|
this._lifetime.store(instance, this._cleanup);
|
|
|
|
|
|
return instance;
|
|
|
}
|
|
|
|
|
|
|
|
|
toString() {
|
|
|
return `[object DescriptorImpl, lifetime=${String(this._lifetime)}]`;
|
|
|
}
|
|
|
}
|
|
|
|