UNPKG

@sustain/core

Version:

Sustain is a Framework that is barely used despedcies to make stable and sustainable apps

83 lines 3.42 kB
"use strict"; // 2018-2019 Darcy Rayner // 2019 Labidi Aymen (labidi@aymen.co) Object.defineProperty(exports, "__esModule", { value: true }); exports.Container = void 0; const provider_1 = require("./provider"); const injectable_1 = require("./injectable"); require("reflect-metadata"); const inject_1 = require("./inject"); const REFLECT_PARAMS = 'design:paramtypes'; class Container { constructor() { this.providers = new Map(); } addProvider(provider) { this.assertInjectableIfClassProvider(provider); this.providers.set(provider.provide, provider); } inject(type) { let 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); } get(type) { return this.providers.get(type).provide; } injectWithProvider(type, provider) { if (provider === undefined) { throw new Error(`No provider for type ${this.getTokenName(type)}`); } if (provider_1.isClassProvider(provider)) { return this.injectClass(provider); } else if (provider_1.isValueProvider(provider)) { return this.injectValue(provider); } else { // Factory provider by process of elimination return this.injectFactory(provider); } } assertInjectableIfClassProvider(provider) { if (provider_1.isClassProvider(provider) && !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); } injectValue(valueProvider) { return valueProvider.useValue; } injectFactory(valueProvider) { return valueProvider.useFactory(); } getInjectedParams(target) { const argTypes = Reflect.getMetadata(REFLECT_PARAMS, target); 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 = inject_1.getInjectionToken(target, index); const actualToken = overrideToken === undefined ? argType : overrideToken; let provider = this.providers.get(actualToken); return this.injectWithProvider(actualToken, provider); }); } getTokenName(token) { return token instanceof provider_1.InjectionToken ? token.injectionIdentifier : token.name; } } exports.Container = Container; //# sourceMappingURL=container.js.map