@blynx/inject
Version:
Dependency injector for javascript
123 lines (122 loc) • 4.32 kB
JavaScript
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
require("reflect-metadata");
var inject_provider_1 = require("./inject.provider");
var getOptions_1 = require("./getOptions");
var constants_1 = require("./constants");
var getName_1 = require("./getName");
function getNewConstructor(constructor, params) {
return /** @class */ (function (_super) {
__extends(class_1, _super);
function class_1() {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
var _this = this;
var newParams = params.slice(0);
for (var j = 0; j < args.length; j++) {
var arg = args[j];
for (var i = 0; i < newParams.length; i++) {
if (newParams[i] === void 0) {
newParams[i] = arg;
break;
}
}
}
_this = _super.apply(this, newParams) || this;
return _this;
}
return class_1;
}(constructor));
}
function getParams(excludes, metadata) {
var params = [];
for (var i = 0; i < metadata.length; i++) {
var meta = metadata[i];
var key = getName_1.getName(meta);
if (excludes[key] !== true) {
params.push(inject_provider_1.InjectProvider.Instance.get(meta));
}
else {
params.push(void 0);
}
}
return params;
}
function setupNewConstructorPrototype(originalConstructor, newConstructor) {
newConstructor.prototype = Object.create(originalConstructor.prototype);
newConstructor.prototype.constructor = originalConstructor;
Object.defineProperty(newConstructor, 'name', { value: getName_1.getName(originalConstructor), enumerable: false, writable: false });
}
/**
* Inject dependencies into constructor
*
* @export
* @param {IInjectOptions} [options={}] Options
* @param {Function} constructor Constructor to inject into
* @returns {Function} New constructor
*/
function Inject(options, constructor) {
var metadata = Reflect.getMetadata(constants_1.ParamTypes, constructor);
if (metadata != null) {
var params = getParams(options.exclude, metadata);
var newConstructor = getNewConstructor(constructor, params);
setupNewConstructorPrototype(constructor, newConstructor);
var newMetadata = [];
for (var i = 0; i < metadata.length; i++) {
var meta = metadata[i];
if (options.exclude[getName_1.getName(meta)] === true) {
newMetadata.push(meta);
}
}
Reflect.defineMetadata(constants_1.ParamTypes, newMetadata, newConstructor);
return newConstructor;
}
else {
return constructor;
}
}
/**
* Decorate an object as Injectable into classes that are also decorated as Injectable
*
* @export
* @param {IInjectableOptions} [options={}] Options
* @returns Decorator
*/
function Injectable(options) {
if (options === void 0) { options = {}; }
options = getOptions_1.getOptions(options, defaultOptions);
return function (constructor) {
inject_provider_1.InjectProvider.Instance.setName(options.namespace, constructor);
if (options.inject === true) {
constructor = Inject(options, constructor);
}
inject_provider_1.InjectProvider.Instance.register(constructor);
return constructor;
};
}
exports.Injectable = Injectable;
var defaultOptions = {
namespace: '',
exclude: {
String: true,
Number: true,
Object: true,
Array: true,
Boolean: true
},
inject: true
};