UNPKG

@asuka/di

Version:
185 lines 7.67 kB
import { __read, __spread, __values } from "tslib"; import { ReflectiveProvider } from './injector-provider'; import { InjectionProvider } from './provider'; var Injector = (function () { function Injector(parent) { if (parent === void 0) { parent = null; } this.parent = parent; this.provider = new InjectionProvider(); this.resolvedProviders = new Map(); this.providersCache = new Map(); } Injector.prototype.addProvider = function (provider) { return this.provider.addProvider(provider); }; Injector.prototype.addProviders = function (providers) { var e_1, _a; try { for (var providers_1 = __values(providers), providers_1_1 = providers_1.next(); !providers_1_1.done; providers_1_1 = providers_1.next()) { var provider = providers_1_1.value; this.provider.addProvider(provider); } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (providers_1_1 && !providers_1_1.done && (_a = providers_1.return)) _a.call(providers_1); } finally { if (e_1) throw e_1.error; } } return this; }; Injector.prototype.getInstance = function (provider) { return this._getInstance(provider, true); }; Injector.prototype.resolveAndInstantiate = function (provider) { return this._getInstance(provider, false); }; Injector.prototype.createChild = function (providers) { var e_2, _a; var childInjector = new Injector(this); try { for (var providers_2 = __values(providers), providers_2_1 = providers_2.next(); !providers_2_1.done; providers_2_1 = providers_2.next()) { var provider = providers_2_1.value; childInjector.provider.addProvider(provider); } } catch (e_2_1) { e_2 = { error: e_2_1 }; } finally { try { if (providers_2_1 && !providers_2_1.done && (_a = providers_2.return)) _a.call(providers_2); } finally { if (e_2) throw e_2.error; } } return childInjector; }; Injector.prototype.resolveReflectiveProvider = function (provider) { var _a; var reflectiveProvider = null; if (this.provider.findProviderByToken((_a = provider.provide, (_a !== null && _a !== void 0 ? _a : provider)))) { if (this.providersCache.has(provider)) { return this.providersCache.get(provider); } reflectiveProvider = new ReflectiveProvider(provider); this.providersCache.set(provider, reflectiveProvider); } return reflectiveProvider; }; Injector.prototype._getInstance = function (provider, useCache) { var injector = this; var instance = null; var reflectiveProvider = null; var deps = this._findDeps(provider); while (injector) { reflectiveProvider = injector.resolveReflectiveProvider(provider); if (!reflectiveProvider) { injector = injector.parent; continue; } if (injector.resolvedProviders.has(reflectiveProvider)) { if (deps) { if (useCache && (injector === this || this._checkDepenciesClean(injector, deps))) { instance = injector.resolvedProviders.get(reflectiveProvider); } else { instance = this._resolveByReflectiveProvider(reflectiveProvider, false, this); if (useCache) { this.resolvedProviders.set(reflectiveProvider, instance); } } } else { instance = injector.resolvedProviders.get(reflectiveProvider); } break; } instance = injector._resolveByReflectiveProvider(reflectiveProvider, useCache, this); if (instance) { if (useCache) { injector.resolvedProviders.set(reflectiveProvider, instance); } break; } injector = injector.parent; } if (!instance) { reflectiveProvider = new ReflectiveProvider(provider); throw new TypeError("No provider for " + reflectiveProvider.name + "!"); } return instance; }; Injector.prototype._resolveByReflectiveProvider = function (reflectiveProvider, useCache, leaf) { var _a; if (useCache === void 0) { useCache = true; } if (leaf === void 0) { leaf = this; } var _b; var instance = null; var provider = reflectiveProvider.provider, name = reflectiveProvider.name; if (typeof provider === 'function') { var deps = (_b = Reflect.getMetadata('design:paramtypes', provider), (_b !== null && _b !== void 0 ? _b : [])); var depsInstance = deps.map(function (dep) { return leaf._getInstance(leaf._findExisting(dep), useCache); }); instance = new (provider.bind.apply(provider, __spread([void 0], depsInstance)))(); } else if (provider.useValue) { instance = provider.useValue; } else if (provider.useClass) { instance = leaf._getInstance(provider.useClass, useCache); } else if (provider.useFactory) { var deps = []; if (provider.deps) { deps = provider.deps.map(function (dep) { return leaf._getInstance(leaf._findExisting(dep), useCache); }); } instance = (_a = provider).useFactory.apply(_a, __spread(deps)); } else if (provider.useExisting) { instance = leaf._getInstance(this._findExisting(provider.useExisting), useCache); } if (!instance) { throw new TypeError("Can not resolve " + name + ", it's not a valid provider"); } return instance; }; Injector.prototype._findExisting = function (token) { var _a; var provider = null; var injector = this; while (injector) { provider = injector.provider.findProviderByToken(token); if (provider) { break; } injector = injector.parent; } if (!provider) { throw new TypeError("No provider for " + (_a = token.name, (_a !== null && _a !== void 0 ? _a : token.toString()))); } return provider; }; Injector.prototype._findDeps = function (provider) { return typeof provider === 'function' ? Reflect.getMetadata('design:paramtypes', provider) : provider.useClass ? Reflect.getMetadata('design:paramtypes', provider.useClass) : provider.deps ? provider.deps : null; }; Injector.prototype._checkDepenciesClean = function (leaf, deps) { var _this = this; return deps.every(function (dep) { var depInLeaf = leaf._findExisting(dep); var depInRoot = _this._findExisting(dep); var isEqual = depInLeaf === depInRoot; var deps = _this._findDeps(depInLeaf); if (deps) { return _this._checkDepenciesClean(leaf, deps) && isEqual; } return isEqual; }); }; return Injector; }()); export { Injector }; //# sourceMappingURL=injector.js.map