alpha-dic
Version:
Asynchronous dependency injection container
62 lines (61 loc) • 2.8 kB
JavaScript
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`);
}
}
}
;