##// END OF EJS Templates
improved typings
improved typings

File last commit:

r5:83fa5814462d default
r7:58282d42a47b default
Show More
ActivationContext.ts
139 lines | 4.3 KiB | video/mp2t | TypeScriptLexer
/ src / main / ts / ActivationContext.ts
cin
working on fluent configuration
r1 import { Descriptor, ILifetime, RegistrationMap, LifetimeContainer, ConfigurableKeys } from "./interfaces";
cin
Working on container builder
r5 import { LifetimeManager } from "./LifetimeManager";
cin
working on fluent configuration
r1 import { argumentNotNull } from "./traits";
cin
initial commit
r0
export interface ActivationContextInfo {
name: string;
service: string;
}
let nextId = 1;
/** This class is created once per `Container.resolve` method call and used to
* cache dependencies and to track created instances. The activation context
* tracks services with `context` activation type.
*/
export class ActivationContext<S extends object> {
cin
ActivationContext removed 'clone' method, rewritten 'enter' method
r3 private readonly _cache: Record<string, unknown>;
cin
initial commit
r0
cin
ActivationContext removed 'clone' method, rewritten 'enter' method
r3 private readonly _services: Partial<RegistrationMap<S>>;
cin
initial commit
r0
cin
ActivationContext removed 'clone' method, rewritten 'enter' method
r3 private readonly _name: string;
cin
initial commit
r0
cin
ActivationContext removed 'clone' method, rewritten 'enter' method
r3 private readonly _service: Descriptor<S, unknown>;
cin
initial commit
r0
cin
Working on container builder
r5 private readonly _containerLifetimeManager: LifetimeManager;
cin
initial commit
r0
cin
ActivationContext removed 'clone' method, rewritten 'enter' method
r3 private readonly _parent: ActivationContext<S> | undefined;
cin
initial commit
r0
/** Creates a new activation context with the specified parameters.
cin
working on fluent configuration
r1 * @param containerLifetimeManager the container which starts the activation process
cin
initial commit
r0 * @param services the initial service registrations
* @param name the name of the service being activated, this parameter is
* used for the debug purpose.
* @param service the service to activate, this parameter is used for the
* debug purpose.
*/
cin
Working on container builder
r5 constructor(containerLifetimeManager: LifetimeManager, services: Partial<RegistrationMap<S>>, name: string, service: Descriptor<S, unknown>, cache = {}) {
cin
initial commit
r0 this._name = name;
this._service = service;
cin
ActivationContext removed 'clone' method, rewritten 'enter' method
r3 this._cache = cache;
cin
initial commit
r0 this._services = services;
cin
working on fluent configuration
r1 this._containerLifetimeManager = containerLifetimeManager;
cin
initial commit
r0 }
/** the name of the current resolving dependency */
getName() {
return this._name;
}
cin
working on fluent configuration
r1 createContainerLifetime<T>() {
cin
Working on container builder
r5 return this._containerLifetimeManager.create<T>();
cin
initial commit
r0 }
/** Resolves the specified dependency in the current context
* @param name The name of the dependency being resolved
*/
cin
working on fluent configuration
r1 resolve<K extends keyof S>(name: K): NonNullable<S[K]>;
cin
initial commit
r0 /** Resolves the specified dependency with the specified default value if
* the dependency is missing.
*
* @param name The name of the dependency being resolved
* @param def A default value to return in case of the specified dependency
* is missing.
*/
cin
working on fluent configuration
r1 resolve<K extends keyof S, T>(name: K, def: T): NonNullable<S[K]> | T;
resolve<K extends keyof S, T>(name: K, def?: T): S[K] | T | undefined {
cin
initial commit
r0 const d = this._services[name];
if (d !== undefined) {
return this.activate(d, name.toString());
} else {
if (arguments.length > 1)
return def;
else
cin
working on fluent configuration
r1 throw new Error(`Service ${String(name)} not found`);
cin
initial commit
r0 }
}
/**
* registers services local to the the activation context
*
* @name{string} the name of the service
* @service{string} the service descriptor to register
*/
cin
working on fluent configuration
r1 register<K extends ConfigurableKeys<S>>(name: K, service: RegistrationMap<S>[K]) {
argumentNotNull(name, "name");
cin
initial commit
r0
cin
working on fluent configuration
r1 this._services[name] = service;
cin
initial commit
r0 }
cin
working on fluent configuration
r1 createLifetime<T>(): ILifetime<T> {
cin
initial commit
r0 const id = nextId++;
return {
cin
working on fluent configuration
r1 initialize() {},
has: () => id in this._cache,
get: () => this._cache[id] as T,
store: item => {
this._cache[id] = item;
cin
initial commit
r0 }
};
}
activate<T>(d: Descriptor<S, T>, name: string) {
cin
working on fluent configuration
r1 // TODO: add logging
// if (trace.isLogEnabled())
// trace.log("enter {0} {1}", name, d);
cin
initial commit
r0
const ctx = this.enter(d, name);
const v = d.activate(ctx);
cin
working on fluent configuration
r1 // if (trace.isLogEnabled())
// trace.log(`leave ${name}`);
cin
initial commit
r0
return v;
}
getStack(): ActivationContextInfo[] {
const stack = [{
name: this._name,
service: this._service.toString()
}];
return this._parent ?
stack.concat(this._parent.getStack()) :
stack;
}
cin
ActivationContext removed 'clone' method, rewritten 'enter' method
r3 private enter(service: Descriptor<S, unknown>, name: string) {
return new ActivationContext(
this._containerLifetimeManager,
Object.create(this._services) as typeof this._services,
name,
service,
this._cache
);
cin
initial commit
r0 }
}