ReferenceDescriptor.ts
99 lines
| 2.8 KiB
| video/mp2t
|
TypeScriptLexer
|
|
r114 | import { isNull, argumentNotEmptyString, each, keys } from "../safe"; | ||
|
|
r49 | import { ActivationContext } from "./ActivationContext"; | ||
|
|
r115 | import { ServiceMap, Descriptor, PartialServiceMap } from "./interfaces"; | ||
|
|
r49 | import { ActivationError } from "./ActivationError"; | ||
|
|
r113 | export interface ReferenceDescriptorParams<S, K extends keyof S> { | ||
| name: K; | ||||
|
|
r49 | lazy?: boolean; | ||
| optional?: boolean; | ||||
|
|
r113 | default?: S[K]; | ||
|
|
r115 | services?: PartialServiceMap<S>; | ||
|
|
r49 | } | ||
|
|
r115 | function defined<T>(v: T | undefined) { | ||
|
|
r114 | if (v === undefined) | ||
| throw Error(); | ||||
| return v; | ||||
| } | ||||
|
|
r115 | export class ReferenceDescriptor<S = any, K extends keyof S = keyof S> implements Descriptor<S, S[K] | ((args?: PartialServiceMap<S> ) => S[K])> { | ||
|
|
r113 | _name: K; | ||
|
|
r49 | |||
| _lazy = false; | ||||
| _optional = false; | ||||
|
|
r115 | _default: S[K] | undefined; | ||
|
|
r49 | |||
|
|
r118 | _services: PartialServiceMap<S>; | ||
|
|
r49 | |||
|
|
r113 | constructor(opts: ReferenceDescriptorParams<S, K>) { | ||
|
|
r49 | argumentNotEmptyString(opts && opts.name, "opts.name"); | ||
| this._name = opts.name; | ||||
| this._lazy = !!opts.lazy; | ||||
| this._optional = !!opts.optional; | ||||
| this._default = opts.default; | ||||
|
|
r113 | |||
|
|
r115 | this._services = (opts.services || {}) as ServiceMap<S>; | ||
|
|
r49 | } | ||
|
|
r114 | activate(context: ActivationContext<S>) { | ||
|
|
r49 | // добавляем сервисы | ||
| if (this._services) { | ||||
|
|
r115 | each(this._services, (v, k) => context.register(k, v)); | ||
|
|
r49 | } | ||
| if (this._lazy) { | ||||
| const saved = context.clone(); | ||||
|
|
r115 | return (cfg?: PartialServiceMap<S>) => { | ||
|
|
r49 | // защищаем контекст на случай исключения в процессе | ||
| // активации | ||||
| const ct = saved.clone(); | ||||
| try { | ||||
| if (cfg) { | ||||
|
|
r118 | each(cfg, (v, k) => ct.register(k, v)); | ||
|
|
r49 | } | ||
| return this._optional ? ct.resolve(this._name, this._default) : ct | ||||
| .resolve(this._name); | ||||
| } catch (error) { | ||||
|
|
r113 | throw new ActivationError(this._name.toString(), ct.getStack(), error); | ||
|
|
r49 | } | ||
| }; | ||||
| } else { | ||||
| const v = this._optional ? | ||||
| context.resolve(this._name, this._default) : | ||||
| context.resolve(this._name); | ||||
| return v; | ||||
| } | ||||
| } | ||||
| toString() { | ||||
| const opts = []; | ||||
| if (this._optional) | ||||
| opts.push("optional"); | ||||
| if (this._lazy) | ||||
| opts.push("lazy"); | ||||
| const parts = [ | ||||
| "@ref " | ||||
| ]; | ||||
| if (opts.length) { | ||||
| parts.push("{"); | ||||
| parts.push(opts.join()); | ||||
| parts.push("} "); | ||||
| } | ||||
|
|
r113 | parts.push(this._name.toString()); | ||
|
|
r49 | |||
|
|
r115 | if (this._default !== undefined && this._default !== null) { | ||
|
|
r49 | parts.push(" = "); | ||
|
|
r115 | parts.push(String(this._default)); | ||
|
|
r49 | } | ||
| return parts.join(""); | ||||
| } | ||||
| } | ||||
