UNPKG

alpha-dic

Version:

Asynchronous dependency injection container

62 lines (61 loc) 2.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createDefinitionFromMetadata = exports.getMetadata = exports.ensureMetadata = void 0; const Definition_1 = require("./Definition"); const errors = require("./errors"); const serviceFactories_1 = require("./serviceFactories"); require('reflect-metadata'); const KEY = Symbol('__alphaDic-ServiceMetadata'); /** * Creates service metadata data for given class if it doesn't exist. Otherwise returns current service metadata. */ function ensureMetadata(target) { let data = getMetadata(target); if (!data) { data = { clazz: target, propertiesInjectors: new Map(), constructorArguments: [], annotations: [] }; Reflect.defineMetadata(KEY, data, target); } return data; } exports.ensureMetadata = ensureMetadata; function getMetadata(target) { return Reflect.getMetadata(KEY, target); } exports.getMetadata = getMetadata; function createDefinitionFromMetadata(metadata, constructor) { assertValidServiceDefinition(constructor, metadata); const definition = new Definition_1.Definition(metadata.name); const args = metadata.constructorArguments.concat(Array.from(metadata.propertiesInjectors.values())); return definition.withArgs(...args) .useFactory((...args) => { // create service from constructor const constructorArgs = args.slice(0, metadata.constructorArguments.length); const service = serviceFactories_1.fromConstructor(constructor)(...constructorArgs); // inject to properties const propertiesInjectionsStartIndex = metadata.constructorArguments.length; let propertyInjectionIndex = 0; for (const [propertyName] of metadata.propertiesInjectors.entries()) { service[propertyName] = args[propertiesInjectionsStartIndex + propertyInjectionIndex++]; } return service; }) .markType(metadata.clazz) .annotate(...metadata.annotations); } exports.createDefinitionFromMetadata = createDefinitionFromMetadata; function assertValidServiceDefinition(constructor, metadata) { if (constructor.length > metadata.constructorArguments.length) { throw errors.INVALID_SERVICE_ARGUMENTS_LENGTH(`Invalid service "${metadata.name.toString()}" definition. Required constructor arguments: ${constructor.length}, provided: ${metadata.constructorArguments.length}`); } for (let i = 0; i < metadata.constructorArguments.length; i++) { const arg = metadata.constructorArguments[i]; if (!arg) { throw errors.MISSING_INJECT_DECORATOR(`Missing @Inject decorator for argument at position "${i}". Every constructor argument needs to have @Inject decorator`); } } }