Container.ts
128 lines
| 3.4 KiB
| video/mp2t
|
TypeScriptLexer
|
|
r33 | import { ActivationContext } from "./ActivationContext"; | ||
|
|
r34 | import { ValueDescriptor } from "./ValueDescriptor"; | ||
| import { ActivationError } from "./ActivationError"; | ||||
|
|
r44 | import { isDescriptor, ServiceMap } from "./interfaces"; | ||
|
|
r42 | import { TraceSource } from "../log/TraceSource"; | ||
|
|
r44 | import { Configuration } from "./Configuration"; | ||
| import { Cancellation } from "../Cancellation"; | ||||
|
|
r42 | |||
| const trace = TraceSource.get("@implab/core/di/ActivationContext"); | ||||
|
|
r33 | |||
| export class Container { | ||||
|
|
r38 | _services: ServiceMap; | ||
|
|
r33 | |||
|
|
r38 | _cache: object; | ||
| _cleanup: (() => void)[]; | ||||
|
|
r33 | |||
|
|
r38 | _root: Container; | ||
|
|
r33 | |||
|
|
r38 | _parent: Container; | ||
|
|
r33 | |||
| constructor(parent?: Container) { | ||||
| this._parent = parent; | ||||
| this._services = parent ? Object.create(parent._services) : {}; | ||||
| this._cache = {}; | ||||
| this._cleanup = []; | ||||
| this._root = parent ? parent.getRootContainer() : this; | ||||
| this._services.container = new ValueDescriptor(this); | ||||
| } | ||||
| getRootContainer() { | ||||
| return this._root; | ||||
| } | ||||
| getParent() { | ||||
| return this._parent; | ||||
| } | ||||
|
|
r41 | resolve(name: string, def?) { | ||
|
|
r44 | trace.debug("resolve {0}", name); | ||
|
|
r38 | const d = this._services[name]; | ||
|
|
r41 | if (d === undefined) { | ||
|
|
r33 | if (arguments.length > 1) | ||
| return def; | ||||
| else | ||||
| throw new Error("Service '" + name + "' isn't found"); | ||||
|
|
r41 | } | ||
|
|
r33 | |||
|
|
r38 | const context = new ActivationContext(this, this._services); | ||
|
|
r33 | try { | ||
|
|
r41 | return context.activate(d, name); | ||
|
|
r33 | } catch (error) { | ||
| throw new ActivationError(name, context.getStack(), error); | ||||
| } | ||||
| } | ||||
|
|
r42 | /** | ||
| * @deprecated use resolve() method | ||||
| */ | ||||
|
|
r44 | getService() { | ||
|
|
r41 | return this.resolve.apply(this, arguments); | ||
| } | ||||
|
|
r33 | register(nameOrCollection, service?) { | ||
|
|
r38 | if (arguments.length === 1) { | ||
| const data = nameOrCollection; | ||||
| for (const name in data) | ||||
|
|
r33 | this.register(name, data[name]); | ||
| } else { | ||||
|
|
r41 | if (!isDescriptor(service)) | ||
| throw new Error("The service parameter must be a descriptor"); | ||||
|
|
r33 | this._services[nameOrCollection] = service; | ||
| } | ||||
| return this; | ||||
| } | ||||
| onDispose(callback) { | ||||
| if (!(callback instanceof Function)) | ||||
| throw new Error("The callback must be a function"); | ||||
| this._cleanup.push(callback); | ||||
| } | ||||
| dispose() { | ||||
| if (this._cleanup) { | ||||
|
|
r38 | for (const f of this._cleanup) | ||
| f(); | ||||
|
|
r33 | this._cleanup = null; | ||
| } | ||||
| } | ||||
| /** | ||||
| * @param{String|Object} config | ||||
| * The configuration of the contaier. Can be either a string or an object, | ||||
| * if the configuration is an object it's treated as a collection of | ||||
| * services which will be registed in the contaier. | ||||
|
|
r38 | * | ||
|
|
r33 | * @param{Function} opts.contextRequire | ||
| * The function which will be used to load a configuration or types for services. | ||||
|
|
r38 | * | ||
|
|
r33 | */ | ||
|
|
r44 | async configure(config: string | object, opts?: any, ct = Cancellation.none) { | ||
| const c = new Configuration(this); | ||||
|
|
r33 | if (typeof (config) === "string") { | ||
|
|
r44 | return c.loadConfiguration(config, ct); | ||
|
|
r33 | } else { | ||
|
|
r44 | return c.applyConfiguration(config, opts && opts.contextRequire, ct); | ||
|
|
r33 | } | ||
| } | ||||
| createChildContainer() { | ||||
| return new Container(this); | ||||
| } | ||||
| has(id) { | ||||
| return id in this._cache; | ||||
| } | ||||
| get(id) { | ||||
| return this._cache[id]; | ||||
| } | ||||
| store(id, value) { | ||||
| return (this._cache[id] = value); | ||||
| } | ||||
|
|
r38 | } | ||
