##// END OF EJS Templates
Refactoring, working on services lifetime
Refactoring, working on services lifetime

File last commit:

r131:674555892e14 ioc ts support
r131:674555892e14 ioc ts support
Show More
ActivationContext.ts
123 lines | 3.1 KiB | video/mp2t | TypeScriptLexer
/ src / main / ts / di / ActivationContext.ts
import { TraceSource } from "../log/TraceSource";
import { argumentNotNull, argumentNotEmptyString } from "../safe";
import { Descriptor, ContainerServiceMap, ContainerKeys, ContainerResolve } from "./interfaces";
import { Container } from "./Container";
import { MapOf } from "../interfaces";
const trace = TraceSource.get("@implab/core/di/ActivationContext");
export interface ActivationContextInfo {
name: string;
service: string;
}
export class ActivationContext<S extends object> {
_cache: MapOf<any>;
_services: ContainerServiceMap<S>;
_visited: MapOf<any>;
_name: string;
_service: Descriptor<S, any>;
_container: Container<S>;
_parent: ActivationContext<S> | undefined;
constructor(container: Container<S>, services: ContainerServiceMap<S>, name: string, service: Descriptor<S, any>) {
this._name = name;
this._service = service;
this._visited = {};
this._cache = {};
this._services = services;
this._container = container;
}
getName() {
return this._name;
}
getContainer() {
return this._container;
}
resolve<K extends ContainerKeys<S>>(name: K, def?: ContainerResolve<S, K>) {
const d = this._services[name];
if (d !== undefined) {
return this.activate(d, name.toString());
} else {
if (def !== undefined && def !== null)
return def;
else
throw new Error(`Service ${name} not found`);
}
}
/**
* registers services local to the the activation context
*
* @name{string} the name of the service
* @service{string} the service descriptor to register
*/
register<K extends keyof S>(name: K, service: Descriptor<S, S[K]>) {
argumentNotEmptyString(name, "name");
this._services[name] = service as any;
}
has(id: string) {
return id in this._cache;
}
get<T>(id: string) {
return this._cache[id];
}
store(id: string, value: any) {
return (this._cache[id] = value);
}
activate<T>(d: Descriptor<S, T>, name: string) {
if (trace.isLogEnabled())
trace.log(`enter ${name} ${d}`);
const ctx = this.enter(d, name);
const v = d.activate(ctx);
if (trace.isLogEnabled())
trace.log(`leave ${name}`);
return v;
}
visit(id: string) {
const count = this._visited[id] || 0;
this._visited[id] = count + 1;
return count;
}
getStack(): ActivationContextInfo[] {
const stack = [{
name: this._name,
service: this._service.toString()
}];
return this._parent ?
stack.concat(this._parent.getStack()) :
stack;
}
private enter(service: Descriptor<S, any>, name: string): this {
const clone = Object.create(this);
clone._name = name;
clone._services = Object.create(this._services);
clone._parent = this;
clone._service = service;
return clone;
}
}