import { Container } from "./Container"; import { DescriptorBuilder } from "./DescriptorBuilder"; import { Configurable, ConfigurableKeys, ContainerServices, Descriptor, IContainerBuilder, IDescriptorBuilder, RegistrationMap, ServiceContainer } from "./interfaces"; import { LifetimeManager } from "./LifetimeManager"; export class ContainerBuilder> implements IContainerBuilder{ private _pending = 1; private readonly _services: Partial>>; private readonly _lifetimeManager = new LifetimeManager(); constructor(parentServices?: object) { this._services = Object.create(parentServices ? parentServices : null) as object; } createServiceBuilder(name: K): IDescriptorBuilder, NonNullable, object, keyof S> { return new DescriptorBuilder(this._lifetimeManager, this._register(name), this._fail); } build(): ServiceContainer { this._assertBuilding(); if(!this._complete()) throw new Error("The configuration didn't complete."); return new Container(this._services, this._lifetimeManager); } private readonly _register = >(name: K) => (descriptor: Descriptor>) => { this._complete(); this._services[name] = descriptor; }; private readonly _fail = (ex: unknown) => { }; private _assertBuilding() { throw new Error("The descriptor builder is finalized"); } private _complete() { return !(--this._pending); } }