@web-atoms/core-docs
Version:
134 lines • 5.35 kB
JavaScript
(function (factory) {
if (typeof module === "object" && typeof module.exports === "object") {
var v = factory(require, exports);
if (v !== undefined) module.exports = v;
}
else if (typeof define === "function" && define.amd) {
define(["require", "exports", "../core/TransientDisposable", "../core/types", "./Inject", "./ServiceCollection", "./TypeKey"], factory);
}
})(function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ServiceProvider = void 0;
const TransientDisposable_1 = require("../core/TransientDisposable");
const types_1 = require("../core/types");
const Inject_1 = require("./Inject");
const ServiceCollection_1 = require("./ServiceCollection");
const TypeKey_1 = require("./TypeKey");
class ServiceProvider {
constructor(parent) {
this.parent = parent;
this.instances = {};
if (parent === null) {
ServiceCollection_1.ServiceCollection.instance.registerScoped(ServiceProvider);
}
const sd = ServiceCollection_1.ServiceCollection.instance.get(ServiceProvider);
this.instances[sd.id] = this;
}
get global() {
return this.parent === null ? this : this.parent.global;
}
get(key) {
return this.resolve(key, true);
}
put(key, value) {
let sd = ServiceCollection_1.ServiceCollection.instance.get(key);
if (!sd) {
sd = ServiceCollection_1.ServiceCollection.instance.register(key, () => value, ServiceCollection_1.Scope.Global);
}
this.instances[sd.id] = value;
}
resolve(key, create = false, defValue) {
const sd = ServiceCollection_1.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 === ServiceCollection_1.Scope.Global) {
return this.global.getValue(sd);
}
if (sd.scope === ServiceCollection_1.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 === ServiceCollection_1.Scope.Transient) {
return sd.factory(this);
}
let v = this.instances[sd.id];
if (!v) {
this.instances[sd.id] = v = sd.factory(this);
}
return v;
}
newScope() {
return new ServiceProvider(this);
}
dispose() {
for (const key in this.instances) {
if (this.instances.hasOwnProperty(key)) {
const element = this.instances[key];
if (element === this) {
continue;
}
const d = element;
if (d.dispose) {
d.dispose();
}
}
}
}
create(key) {
const originalKey = key;
const originalTypeKey = TypeKey_1.TypeKey.get(originalKey);
if (types_1.DI.resolveType) {
const mappedType = ServiceProvider.mappedTypes[originalTypeKey] || (ServiceProvider.mappedTypes[originalTypeKey] = types_1.DI.resolveType(originalKey));
key = mappedType;
}
const typeKey1 = TypeKey_1.TypeKey.get(key);
const plist = Inject_1.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_1.default) {
iterator.registerIn(value);
}
}
}
else {
value = new (key)();
}
const propList = Inject_1.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_1.default) {
d.registerIn(value);
}
}
}
}
return value;
}
}
exports.ServiceProvider = ServiceProvider;
ServiceProvider.mappedTypes = {};
});
//# sourceMappingURL=ServiceProvider.js.map