ContainerBuilder.ts
65 lines
| 2.0 KiB
| video/mp2t
|
TypeScriptLexer
|
|
r5 | import { Container } from "./Container"; | |
| import { DescriptorBuilder } from "./DescriptorBuilder"; | |||
|
|
r9 | import { Descriptor, IContainerBuilder, IDescriptorBuilder, DescriptorMap, ServiceLocator, ILifetime, IDestroyable } from "./interfaces"; | |
| import { emptyLifetime, LifetimeManager } from "./LifetimeManager"; | |||
|
|
r11 | import { isDestroyable, prototype } from "./traits"; | |
|
|
r5 | ||
|
|
r9 | /** | |
| * Container builder used to prepare service descriptors and create a IoC container | |||
| */ | |||
| export class ContainerBuilder<S, U extends keyof S> implements | |||
| IContainerBuilder<S, U> { | |||
|
|
r5 | ||
| private _pending = 1; | |||
|
|
r9 | private readonly _services: DescriptorMap<S>; | |
|
|
r5 | ||
| private readonly _lifetimeManager = new LifetimeManager(); | |||
|
|
r9 | private readonly _lifetime: ILifetime<IDestroyable>; | |
|
|
r11 | constructor(parentServices: DescriptorMap<S> | null = null, lifetime?: ILifetime<IDestroyable>) { | |
| this._services = prototype(parentServices); | |||
|
|
r9 | this._lifetimeManager = new LifetimeManager(); | |
| this._lifetime = lifetime ?? emptyLifetime(); | |||
|
|
r5 | } | |
|
|
r9 | createServiceBuilder<K extends U>(name: K): | |
| IDescriptorBuilder<S, S[K], Record<never, never>, U> { | |||
|
|
r5 | ||
| return new DescriptorBuilder(this._lifetimeManager, this._register(name), this._fail); | |||
|
|
r9 | ||
|
|
r5 | } | |
|
|
r9 | build(): ServiceLocator<S> { | |
|
|
r5 | this._assertBuilding(); | |
|
|
r9 | if (!this._complete()) | |
|
|
r5 | throw new Error("The configuration didn't complete."); | |
|
|
r9 | ||
|
|
r12 | const {remove, store} = this._lifetime(null); | |
|
|
r9 | ||
|
|
r12 | const container = new Container(this._services, this._lifetimeManager, remove); | |
|
|
r9 | ||
|
|
r12 | store(container); | |
|
|
r9 | ||
| return container; | |||
|
|
r5 | } | |
|
|
r9 | private readonly _register = <K extends U>(name: K) => | |
| (descriptor: Descriptor<S, S[K]>) => { | |||
| this._complete(); | |||
| this._services[name] = descriptor; | |||
| }; | |||
|
|
r5 | ||
| private readonly _fail = (ex: unknown) => { | |||
|
|
r9 | throw ex; | |
|
|
r5 | }; | |
| private _assertBuilding() { | |||
|
|
r9 | if (!this._pending) | |
| throw new Error("The descriptor builder is finalized"); | |||
|
|
r5 | } | |
| private _complete() { | |||
| return !(--this._pending); | |||
| } | |||
| } |
