##// END OF EJS Templates
ActivationContext removed 'clone' method, rewritten 'enter' method
ActivationContext removed 'clone' method, rewritten 'enter' method

File last commit:

r1:a51ea59f0423 default
r3:8a4027b4c19f default
Show More
Container.ts
79 lines | 3.2 KiB | video/mp2t | TypeScriptLexer
cin
initial commit
r0 import { ActivationContext } from "./ActivationContext";
import { ActivationError } from "./ActivationError";
cin
working on fluent configuration
r1 import { RegistrationMap, ContainerKeys, ServiceContainer, ContainerServices, ConfigurableServices, ConfigurableKeys, ServiceLocator, Descriptor} from "./interfaces";
cin
initial commit
r0 import { LifetimeManager } from "./LifetimeManager";
cin
working on fluent configuration
r1 import { each, isKey } from "./traits";
cin
initial commit
r0
cin
working on fluent configuration
r1 export class Container<S extends object > implements ServiceContainer<S> {
private readonly _services: Partial<RegistrationMap<ContainerServices<S>>>;
cin
initial commit
r0
cin
working on fluent configuration
r1 private readonly _lifetimeManager: LifetimeManager;
cin
initial commit
r0
cin
working on fluent configuration
r1 private readonly _cleanup: (() => void)[];
cin
initial commit
r0
cin
working on fluent configuration
r1 private _disposed: boolean;
cin
initial commit
r0
constructor(parent?: Container<S>) {
cin
working on fluent configuration
r1 this._services = Object.create(parent ? parent._services : null) as typeof this._services;
cin
initial commit
r0 this._cleanup = [];
cin
working on fluent configuration
r1 this._services.container = { activate: () => this as ServiceLocator<ContainerServices<S>>};
cin
initial commit
r0 this._services.childContainer = { activate: () => this.createChildContainer() };
this._disposed = false;
this._lifetimeManager = new LifetimeManager();
}
cin
working on fluent configuration
r1 register<K extends ConfigurableKeys<S>>(name: K, service: Descriptor<ContainerServices<S>, ConfigurableServices<S>[K]>): void;
register<K extends ConfigurableKeys<S>>(services: {[k in K]: Descriptor<ContainerServices<S>, ConfigurableServices<S>[k]>}): void;
register<K extends ConfigurableKeys<S>>(nameOrCollection: K | {[k in K]: Descriptor<ContainerServices<S>, ConfigurableServices<S>[k]>}, service?: RegistrationMap<ContainerServices<S>>[K]) {
if (!isKey(nameOrCollection)) {
each(nameOrCollection, (v, k) => this.register(k, v));
} else {
if (!service)
throw new Error("The service parameter must be a descriptor");
cin
initial commit
r0
cin
working on fluent configuration
r1 this._services[nameOrCollection] = service;
}
cin
initial commit
r0 }
cin
working on fluent configuration
r1 createChildContainer(): ServiceContainer<S> {
return new Container(this);
cin
initial commit
r0 }
cin
working on fluent configuration
r1 resolve<K extends ContainerKeys<S>>(name: K): NonNullable<ContainerServices<S>[K]>;
resolve<K extends ContainerKeys<S>>(name: K, def: ContainerServices<S>[K]): ContainerServices<S>[K];
resolve<K extends ContainerKeys<S>>(name: K, def?: ContainerServices<S>[K]): ContainerServices<S>[K] | undefined {
// TODO: add logging
// trace.debug("resolve {0}", name);
cin
initial commit
r0 const d = this._services[name];
if (d === undefined) {
if (arguments.length > 1)
return def;
else
cin
working on fluent configuration
r1 throw new Error(`Service '${String(name)}' isn't found`);
cin
initial commit
r0 } else {
cin
working on fluent configuration
r1 const context = new ActivationContext(this, this._services, String(name), d);
cin
initial commit
r0 try {
return d.activate(context);
} catch (error) {
throw new ActivationError(name.toString(), context.getStack(), error);
}
}
}
cin
working on fluent configuration
r1 createLifetime<T>() {
return this._lifetimeManager.create<T>();
cin
initial commit
r0 }
destroy() {
return this.dispose();
}
dispose() {
if (this._disposed)
return;
this._disposed = true;
for (const f of this._cleanup)
f();
this._lifetimeManager.destroy();
}
}