##// END OF EJS Templates
added provided and configure methods to the fluent container configuration, added applyConfig method to the container
added provided and configure methods to the fluent container configuration, added applyConfig method to the container

File last commit:

r142:be7edf08a115 v1.4.0-rc3 default
r142:be7edf08a115 v1.4.0-rc3 default
Show More
Container.ts
172 lines | 6.1 KiB | video/mp2t | TypeScriptLexer
/ src / main / ts / di / Container.ts
cin
changed the project structure
r49 import { ActivationContext } from "./ActivationContext";
import { ValueDescriptor } from "./ValueDescriptor";
import { ActivationError } from "./ActivationError";
cin
Completely removed IoC annotations...
r135 import { ServiceMap, Descriptor, PartialServiceMap, ServiceLocator, ContainerServiceMap, ContainerKeys, TypeOfService } from "./interfaces";
cin
changed the project structure
r49 import { TraceSource } from "../log/TraceSource";
cin
improved interfaces and more tight type checking
r120 import { Configuration, RegistrationMap } from "./Configuration";
cin
changed the project structure
r49 import { Cancellation } from "../Cancellation";
cin
added provided and configure methods to the fluent container configuration, added applyConfig method to the container
r142 import { IDestroyable, PromiseOrValue, ICancellation } from "../interfaces";
cin
configuration interfaces moved to di/Configuration module...
r118 import { isDescriptor } from "./traits";
cin
Refactoring, working on services lifetime
r131 import { LifetimeManager } from "./LifetimeManager";
cin
added provided and configure methods to the fluent container configuration, added applyConfig method to the container
r142 import { each, isString } from "../safe";
import { ContainerConfiguration, FluentRegistrations } from "./fluent/interfaces";
cin
Completely removed IoC annotations...
r135 import { FluentConfiguration } from "./fluent/FluentConfiguration";
cin
changed the project structure
r49
const trace = TraceSource.get("@implab/core/di/ActivationContext");
cin
working on fluent configuration
r133 export class Container<S extends object = any> implements ServiceLocator<S>, IDestroyable {
cin
improved interfaces and more tight type checking
r120 readonly _services: ContainerServiceMap<S>;
cin
changed the project structure
r49
cin
Completely removed IoC annotations...
r135 readonly _lifetimeManager: LifetimeManager;
cin
Refactoring, working on services lifetime
r131
cin
working on IoC configuration
r114 readonly _cleanup: (() => void)[];
cin
changed the project structure
r49
cin
working on IoC configuration
r114 readonly _root: Container<S>;
cin
changed the project structure
r49
cin
working on IoC configuration
r114 readonly _parent?: Container<S>;
cin
changed the project structure
r49
cin
working on IoC configuration
r114 _disposed: boolean;
cin
changed the project structure
r49
cin
working on IoC configuration
r114 constructor(parent?: Container<S>) {
cin
changed the project structure
r49 this._parent = parent;
this._services = parent ? Object.create(parent._services) : {};
this._cleanup = [];
this._root = parent ? parent.getRootContainer() : this;
cin
corrected code to support ts strict mode...
r115 this._services.container = new ValueDescriptor(this) as any;
cin
working on IoC configuration
r114 this._disposed = false;
cin
Refactoring, working on services lifetime
r131 this._lifetimeManager = new LifetimeManager();
cin
changed the project structure
r49 }
getRootContainer() {
return this._root;
}
getParent() {
return this._parent;
}
cin
Refactoring, working on services lifetime
r131 getLifetimeManager() {
return this._lifetimeManager;
}
cin
working on fluent configuration
r133 resolve<K extends ContainerKeys<S>>(name: K, def?: TypeOfService<S, K>): TypeOfService<S, K> {
cin
changed the project structure
r49 trace.debug("resolve {0}", name);
const d = this._services[name];
if (d === undefined) {
cin
working on IoC configuration
r114 if (def !== undefined)
cin
changed the project structure
r49 return def;
else
throw new Error("Service '" + name + "' isn't found");
cin
working on IoC configuration
r114 } else {
cin
changed the project structure
r49
cin
Refactoring, working on services lifetime
r131 const context = new ActivationContext<S>(this, this._services, String(name), d);
cin
working on IoC configuration
r114 try {
cin
Refactoring, working on services lifetime
r131 return d.activate(context);
cin
working on IoC configuration
r114 } catch (error) {
throw new ActivationError(name.toString(), context.getStack(), error);
}
cin
changed the project structure
r49 }
}
/**
* @deprecated use resolve() method
*/
cin
working on fluent configuration
r133 getService<K extends ContainerKeys<S>>(name: K, def?: TypeOfService<S, K>) {
cin
working on IoC configuration
r114 return this.resolve(name, def);
cin
changed the project structure
r49 }
cin
corrected code to support ts strict mode...
r115 register<K extends keyof S>(name: K, service: Descriptor<S, S[K]>): this;
register(services: PartialServiceMap<S>): this;
register<K extends keyof S>(nameOrCollection: K | ServiceMap<S>, service?: Descriptor<S, S[K]>) {
cin
changed the project structure
r49 if (arguments.length === 1) {
cin
working on IoC configuration
r114 const data = nameOrCollection as ServiceMap<S>;
cin
corrected code to support ts strict mode...
r115
cin
Refactoring, working on services lifetime
r131 each(data, (v, k) => this.register(k, v));
cin
changed the project structure
r49 } else {
if (!isDescriptor(service))
throw new Error("The service parameter must be a descriptor");
cin
corrected code to support ts strict mode...
r115 this._services[nameOrCollection as K] = service as any;
cin
changed the project structure
r49 }
return this;
}
cin
working on IoC configuration
r114 onDispose(callback: () => void) {
cin
changed the project structure
r49 if (!(callback instanceof Function))
throw new Error("The callback must be a function");
this._cleanup.push(callback);
}
cin
working on lifetime management
r129 destroy() {
return this.dispose();
}
cin
changed the project structure
r49 dispose() {
cin
working on IoC configuration
r114 if (this._disposed)
return;
this._disposed = true;
for (const f of this._cleanup)
f();
cin
changed the project structure
r49 }
/**
* @param{String|Object} config
cin
tests
r136 * The configuration of the container. Can be either a string or an object,
cin
changed the project structure
r49 * if the configuration is an object it's treated as a collection of
cin
tests
r136 * services which will be registered in the container.
cin
changed the project structure
r49 *
* @param{Function} opts.contextRequire
* The function which will be used to load a configuration or types for services.
*
*/
cin
tests
r136 async configure(config: string | RegistrationMap<S>, opts?: { contextRequire: any; baseModule?: string }, ct = Cancellation.none) {
const _opts = Object.create(opts || null);
cin
changed the project structure
r49
if (typeof (config) === "string") {
cin
tests
r136 _opts.baseModule = config;
const module = await import(config);
if (module && module.default && typeof (module.default.apply) === "function")
return module.default.apply(this);
else
return this._applyLegacyConfig(module, _opts, ct);
cin
changed the project structure
r49 } else {
cin
tests
r136 return this._applyLegacyConfig(config, _opts, ct);
cin
changed the project structure
r49 }
}
cin
added provided and configure methods to the fluent container configuration, added applyConfig method to the container
r142 applyConfig<S2 extends object>(config: Promise<{ default: ContainerConfiguration<S2>; }>, ct?: ICancellation): Promise<Container<S & S2>>;
applyConfig<S2 extends object, P extends string>(config: Promise<{ [p in P]: ContainerConfiguration<S2>; }>, prop: P, ct?: ICancellation): Promise<Container<S & S2>>;
async applyConfig<S2 extends object, P extends string>(
config: Promise<{ [p in P | "default"]: ContainerConfiguration<S2>; }>,
propOrCt?: P | ICancellation,
ct?: ICancellation
): Promise<Container<S & S2>> {
const mod = await config;
let _ct: ICancellation;
let _prop: P | "default";
if (isString(propOrCt)) {
_prop = propOrCt;
_ct = ct || Cancellation.none;
} else {
_ct = propOrCt || Cancellation.none;
_prop = "default";
}
return mod[_prop].apply(this, _ct);
}
cin
tests
r136 async _applyLegacyConfig(config: RegistrationMap<S>, opts: { contextRequire: any; baseModule?: string }, ct = Cancellation.none) {
return new Configuration<S>(this).applyConfiguration(config, opts);
}
cin
Completely removed IoC annotations...
r135 async fluent<K extends keyof S>(config: FluentRegistrations<K, S>, ct = Cancellation.none): Promise<this> {
await new FluentConfiguration<S>().register(config).apply(this, ct);
return this;
}
cin
improved interfaces and more tight type checking
r120 createChildContainer<S2 extends object = S>(): Container<S & S2> {
cin
working on IoC configuration
r114 return new Container<S & S2>(this as any);
cin
changed the project structure
r49 }
}