devextreme
Version:
JavaScript/TypeScript Component Suite for Responsive Web Development
79 lines (78 loc) • 2.7 kB
JavaScript
/**
* DevExtreme (esm/__internal/core/di/index.js)
* Version: 25.2.5
* Build date: Fri Feb 20 2026
*
* Copyright (c) 2012 - 2026 Developer Express Inc. ALL RIGHTS RESERVED
* Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
*/
export class DIContext {
constructor() {
this.instances = new Map;
this.fabrics = new Map;
this.aliases = new Map;
this.antiRecursionSet = new Set;
this.globalDecorators = []
}
register(id, fabric) {
fabric ?? (fabric = id);
this.fabrics.set(id, fabric)
}
registerInstance(id, instance) {
const decoratedInstance = this.applyGlobalDecorators(instance);
this.instances.set(id, decoratedInstance)
}
get(id) {
const instance = this.tryGet(id);
if (instance) {
return instance
}
throw new Error(`DI item is not registered: ${id}`)
}
tryGet(id) {
id = this.resolveAlias(id);
if (this.instances.get(id)) {
return this.instances.get(id)
}
const fabric = this.fabrics.get(id);
if (fabric) {
const instance = this.create(fabric);
const decoratedInstance = this.applyGlobalDecorators(instance);
this.instances.set(id, decoratedInstance);
this.instances.set(fabric, decoratedInstance);
return decoratedInstance
}
return null
}
registerDecorator(decoratorFn) {
if (this.hasInitiatedInstances) {
throw new Error("Cannot register decorator: decorators must be registered before any instances are created or retrieved from the DI container.")
}
this.globalDecorators.push(decoratorFn)
}
get hasInitiatedInstances() {
return this.instances.size > 0
}
applyGlobalDecorators(instance) {
return this.globalDecorators.reduce(((currentInstance, currentDecorator) => currentDecorator(currentInstance)), instance)
}
create(fabric) {
if (this.antiRecursionSet.has(fabric)) {
throw new Error("dependency cycle in DI")
}
this.antiRecursionSet.add(fabric);
const args = fabric.dependencies.map((dependency => this.get(dependency)));
this.antiRecursionSet.delete(fabric);
return new fabric(...args)
}
addAlias(aliasId, id) {
this.aliases.set(aliasId, id)
}
resolveAlias(aliasId) {
let result = aliasId;
while (this.aliases.has(result)) {
result = this.aliases.get(result)
}
return result
}
}