UNPKG

@web-atoms/core-docs

Version:
134 lines 5.35 kB
(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