ContainerBuilder.ts
56 lines
| 1.7 KiB
| video/mp2t
|
TypeScriptLexer
|
|
r5 | import { Container } from "./Container"; | |
| import { DescriptorBuilder } from "./DescriptorBuilder"; | |||
|
|
r15 | import { Descriptor, IContainerBuilder, IDescriptorBuilder, DescriptorMap, ServiceLocator, ILifetimeManager } from "../typings/interfaces"; | |
|
|
r5 | ||
|
|
r9 | /** | |
| * Container builder used to prepare service descriptors and create a IoC container | |||
| */ | |||
|
|
r14 | export class ContainerBuilder<S, U extends keyof S> implements | |
|
|
r9 | IContainerBuilder<S, U> { | |
|
|
r5 | ||
| private _pending = 1; | |||
|
|
r15 | private readonly _services: DescriptorMap<S>; | |
|
|
r5 | ||
|
|
r15 | private readonly _scope: ILifetimeManager[]; | |
|
|
r5 | ||
|
|
r15 | private readonly _level: number; | |
|
|
r9 | ||
|
|
r15 | constructor(parentServices: DescriptorMap<S> | null, scope: ILifetimeManager[] = []) { | |
|
|
r14 | this._services = { ...parentServices }; // create a copy | |
|
|
r15 | this._level = scope.length; | |
| this._scope = scope; | |||
|
|
r5 | } | |
|
|
r15 | createServiceBuilder<K extends U>(name: K): IDescriptorBuilder<S, S[K], Record<never, never>, U> { | |
|
|
r5 | ||
|
|
r15 | return new DescriptorBuilder(this._level, String(name), 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 | ||
|
|
r15 | return new Container(this._services, this._scope); | |
|
|
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); | |||
| } | |||
| } |
