import { ActivationContext } from "./ActivationContext"; import { ActivationError } from "./ActivationError"; import { ContainerBuilder } from "./ContainerBuilder"; import { RegistrationMap, ServiceContainer, ContainerServices, ServiceLocator, IContainerBuilder, Configurable, ContainerKeys} from "./interfaces"; import { LifetimeManager } from "./LifetimeManager"; export class Container> implements ServiceContainer { private readonly _services: Partial>>; private readonly _lifetimeManager: LifetimeManager; private _disposed: boolean; constructor(services: Partial>>, lifetimeManager: LifetimeManager) { this._services = services; this._services.container = { activate: () => this as ContainerServices["container"]}; this._services.childContainer = { activate: () => this.createChildContainer() as ContainerServices["childContainer"] }; this._disposed = false; this._lifetimeManager = lifetimeManager; } createChildContainer(): IContainerBuilder { return new ContainerBuilder(this._services); } resolve>(name: K): NonNullable[K]>; resolve, T>(name: K, def: T): NonNullable[K]> | T; resolve, T>(name: K, def?: T) { // TODO: add logging // trace.debug("resolve {0}", name); const d = this._services[name]; if (d === undefined) { if (arguments.length > 1) return def; else throw new Error(`Service '${String(name)}' isn't found`); } else { const context = new ActivationContext(this._lifetimeManager, this._services, String(name), d); try { return d.activate(context); } catch (error) { throw new ActivationError(name.toString(), context.getStack(), error); } } } destroy() { if (this._disposed) return; this._disposed = true; this._lifetimeManager.destroy(); } }