|
|
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<S extends Configurable<S>> implements IContainerBuilder<S>{
|
|
|
|
|
|
private _pending = 1;
|
|
|
|
|
|
private readonly _services: Partial<RegistrationMap<ContainerServices<S>>>;
|
|
|
|
|
|
private readonly _lifetimeManager = new LifetimeManager();
|
|
|
|
|
|
constructor(parentServices?: object) {
|
|
|
this._services = Object.create(parentServices ? parentServices : null) as object;
|
|
|
}
|
|
|
|
|
|
createServiceBuilder<K extends keyof S>(name: K): IDescriptorBuilder<S, NonNullable<S[K]>, object> {
|
|
|
return new DescriptorBuilder(this._lifetimeManager, this._register(name), this._fail);
|
|
|
}
|
|
|
|
|
|
build(): ServiceContainer<S> {
|
|
|
this._assertBuilding();
|
|
|
if(!this._complete())
|
|
|
throw new Error("The configuration didn't complete.");
|
|
|
return new Container(this._services, this._lifetimeManager);
|
|
|
}
|
|
|
|
|
|
private readonly _register = <K extends ConfigurableKeys<S>>(name: K) => (descriptor: Descriptor<S, NonNullable<S[K]>>) => {
|
|
|
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);
|
|
|
}
|
|
|
|
|
|
}
|