@web-atoms/core
Version:
137 lines (136 loc) • 4.79 kB
JavaScript
System.register(["../core/TransientDisposable", "../core/types", "./Inject", "./ServiceCollection", "./TypeKey"], function (_export, _context) {
"use strict";
var TransientDisposable, DI, InjectedTypes, Scope, ServiceCollection, TypeKey, ServiceProvider;
_export("ServiceProvider", void 0);
return {
setters: [function (_coreTransientDisposable) {
TransientDisposable = _coreTransientDisposable.default;
}, function (_coreTypes) {
DI = _coreTypes.DI;
}, function (_Inject) {
InjectedTypes = _Inject.InjectedTypes;
}, function (_ServiceCollection) {
Scope = _ServiceCollection.Scope;
ServiceCollection = _ServiceCollection.ServiceCollection;
}, function (_TypeKey) {
TypeKey = _TypeKey.TypeKey;
}],
execute: function () {
_export("ServiceProvider", ServiceProvider = class ServiceProvider {
get global() {
return this.parent === null ? this : this.parent.global;
}
constructor(parent) {
this.parent = parent;
this.instances = new Map();
if (parent === null) {
ServiceCollection.instance.registerScoped(ServiceProvider);
}
const sd = ServiceCollection.instance.get(ServiceProvider);
this.instances.set(sd.id, this);
}
get(key) {
return this.resolve(key, true);
}
put(key, value) {
let sd = ServiceCollection.instance.get(key);
if (!sd) {
sd = ServiceCollection.instance.register(key, () => value, Scope.Global);
}
this.instances.set(sd.id, value);
}
resolve(key, create = false, defValue) {
const sd = ServiceCollection.instance.get(key);
if (!sd) {
if (!create) {
if (defValue !== undefined) {
return defValue;
}
throw new Error(`No service registered for type ${key}`);
}
return this.create(key);
}
if (sd.type === ServiceProvider) {
return this;
}
if (sd.scope === Scope.Global) {
return this.global.getValue(sd);
}
if (sd.scope === Scope.Scoped) {
if (this.parent === null) {
throw new Error("Scoped dependency cannot be created on global");
}
}
return this.getValue(sd);
}
getValue(sd) {
if (sd.scope === Scope.Transient) {
return sd.factory(this);
}
let v = this.instances.get(sd.id);
if (v === void 0) {
v = sd.factory(this);
this.instances.set(sd.id, v);
}
return v;
}
newScope() {
return new ServiceProvider(this);
}
dispose() {
var _a;
for (const element of this.instances.values()) {
if (element === this) {
continue;
}
(_a = element.dispose) === null || _a === void 0 ? void 0 : _a.call(element);
}
this.instances.clear();
}
create(key) {
const originalKey = key;
const originalTypeKey = TypeKey.get(originalKey);
if (DI.resolveType) {
let mappedType = ServiceProvider.mappedTypes.get(originalTypeKey);
if (mappedType === void 0) {
mappedType = DI.resolveType(originalKey);
ServiceProvider.mappedTypes.set(originalKey, mappedType);
}
key = mappedType;
}
const typeKey1 = TypeKey.get(key);
const plist = InjectedTypes.getParamList(key, typeKey1);
let value = null;
if (plist) {
const pv = plist.map(x => x ? this.resolve(x) : void 0);
pv.unshift(null);
value = new (key.bind.apply(key, pv))();
for (const iterator of pv) {
if (iterator && iterator instanceof TransientDisposable) {
iterator.registerIn(value);
}
}
} else {
value = new key();
}
const propList = InjectedTypes.getPropertyList(key, typeKey1);
if (propList) {
for (const key1 in propList) {
if (propList.hasOwnProperty(key1)) {
const element = propList[key1];
const d = this.resolve(element);
value[key1] = d;
if (d && d instanceof TransientDisposable) {
d.registerIn(value);
}
}
}
}
return value;
}
});
ServiceProvider.mappedTypes = new Map();
}
};
});
//# sourceMappingURL=ServiceProvider.js.map