UNPKG

dynamicsmobile

Version:

Allows development of off-line mobile and web business apps over the Dynamics Mobile platform. More info on https://www.dynamicsmobile.com

117 lines 4.94 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Container = void 0; require("reflect-metadata"); const inject_1 = require("./inject"); const injectable_1 = require("./injectable"); const provider_1 = require("./provider"); const REFLECT_PARAMS = "design:paramtypes"; class Container { constructor() { this.providers = new Map(); this.replacedProviders = new Map(); this.singletonInstances = new Map(); } clear() { this.providers.clear(); this.replacedProviders.clear(); this.singletonInstances.clear(); } addProvider(provider) { this.assertInjectableIfClassProvider(provider); if (!provider.replace) { this.providers.set(provider.provide, provider); } else { this.providers.delete(provider.provide); this.replacedProviders.set(provider.provide, provider); } } inject(type) { let provider = this.replacedProviders.get(type); if (!provider) { provider = this.providers.get(type); } if (provider === undefined && !(type instanceof provider_1.InjectionToken)) { provider = { provide: type, useClass: type }; this.assertInjectableIfClassProvider(provider); } return this.injectWithProvider(type, provider); } injectWithProvider(type, provider) { if (!provider) { throw new Error(`No provider for type ${this.getTokenName(type)}`); } if ((0, provider_1.isClassProvider)(provider)) { return this.injectClass(provider); } else if ((0, provider_1.isValueProvider)(provider)) { return this.injectValue(provider); } else if ((0, provider_1.isFactoryProvider)(provider)) { // Factory provider by process of elimination return this.injectFactory(provider); } else if ((0, provider_1.isSingletonProvider)(provider)) { // Factory provider by process of elimination return this.injectSingleton(provider); } var p = JSON.stringify(provider); throw new Error(`Uknown DI provider for ${p}, type: ${type}`); } assertInjectableIfClassProvider(provider) { if (((0, provider_1.isSingletonProvider)(provider) || (0, provider_1.isClassProvider)(provider)) && !(0, injectable_1.isInjectable)(provider.useClass)) { throw new Error(`Cannot provide ${this.getTokenName(provider.provide)} using class ${this.getTokenName(provider.useClass)}, ${this.getTokenName(provider.useClass)} isn't injectable`); } } injectClass(classProvider) { const target = classProvider.useClass; const params = this.getInjectedParams(target); return Reflect.construct(target, params); } injectSingleton(classProvider) { const target = classProvider.useClass; var instance = this.singletonInstances.get(target.name); if (!instance) { const params = this.getInjectedParams(target); instance = Reflect.construct(target, params); this.singletonInstances.set(target.name, instance); } return instance; } injectValue(valueProvider) { return valueProvider.useValue; } injectFactory(valueProvider) { return valueProvider.useFactory(); } getInjectedParams(target) { const __argTypes = Reflect.getMetadata(REFLECT_PARAMS, target); const argTypes = __argTypes; if (argTypes === undefined) { return []; } return argTypes.map((argType, index) => { // The reflect-metadata API fails on circular dependencies, and will return undefined // for the argument instead. if (argType === undefined) { throw new Error(`Injection error. Recursive dependency detected in constructor for type ${target.name} with parameter at index ${index}`); } const overrideToken = (0, inject_1.getInjectionToken)(target, index); const actualToken = overrideToken === undefined ? argType : overrideToken; let provider = this.replacedProviders.get(actualToken); if (!provider) provider = this.providers.get(actualToken); if (!provider) throw new Error(`No provider for type ${actualToken.name} in injectable ${target.name}'s constructor. Make sure the type for ${target.name}'s constructor argument #${index} is declared before type ${target.name}`); return this.injectWithProvider(actualToken, provider); }); } getTokenName(token) { return token instanceof provider_1.InjectionToken ? token.injectionIdentifier : token.name; } } exports.Container = Container; //# sourceMappingURL=container.js.map