##// END OF EJS Templates
sync
sync

File last commit:

r15:3985e8405319 tip default
r15:3985e8405319 tip default
Show More
Container.ts
71 lines | 2.3 KiB | video/mp2t | TypeScriptLexer
import { ActivationContext } from "./ActivationContext";
import { ContainerBuilder } from "./ContainerBuilder";
import { LifetimeManager, emptySlot } from "./LifetimeManager";
import { DescriptorMap, IContainerBuilder, IDestroyable, ILifetimeManager, ILifetimeSlot, ServiceLocator } from "../typings/interfaces";
let nextId = 1;
export class Container<S> implements ServiceLocator<S>, IDestroyable {
private readonly _services: DescriptorMap<S>;
private readonly _scope: ILifetimeManager[];
private readonly _containerId = `container-${nextId++}`;
private readonly _slot: ILifetimeSlot<this>;
private _disposed: boolean;
constructor(services: DescriptorMap<S>, parentScope: ILifetimeManager[]) {
this._services = services;
this._disposed = false;
this._scope = parentScope.concat(new LifetimeManager());
// If this container is created inside the parent container scope,
// allocated lifetime slot
this._slot = parentScope.length ?
parentScope[parentScope.length - 1].slot(this._containerId) :
emptySlot<this>();
// store the container reference in the lifetime slot
this._slot.store(this);
}
private _assertNotDestroyed() {
if (this._disposed)
throw new Error("The container is destroyed");
}
createChildBuilder(): IContainerBuilder<S, keyof S> {
this._assertNotDestroyed();
return new ContainerBuilder(this._services, this._scope);
}
resolve<K extends keyof S>(name: K): NonNullable<S[K]>;
resolve<K extends keyof S, T>(name: K, def: T): NonNullable<S[K]> | T;
resolve<K extends keyof S, T>(name: K, def?: T) {
this._assertNotDestroyed();
const context = new ActivationContext(this, this._scope, this._services);
return arguments.length === 1 ?
context.resolve(name, []) :
context.resolve(name, [], def);
}
destroy() {
if (this._disposed)
return;
this._disposed = true;
// destroy own scope
this._scope[this._scope.length - 1].destroy();
// release lifetime slot if the container is destroyed before the parent
// container. If this container is destroyed during the parent container
// cleanup procedure this call will have no effect.
this._slot.remove();
}
}