dotnode
Version:
.NET-like MVC framework for Node.js
115 lines (69 loc) • 2.79 kB
JavaScript
var extend = require('xtend');
var Injector = function () {
this._generatedModules = {};
this._cachedModules = {};
};
// #region public methods
Injector.prototype.createConstructor = function (Constructor, args) {
var Temp = function () {
return Constructor.apply(this, args);
};
Temp.prototype = extend({}, Temp.prototype, Constructor.prototype);
return Temp;
};
Injector.prototype.invoke = function (fn, context, params) {
var paramNames = this._getParameterNames(fn);
var paramValues = paramNames.map(function (name) {
return params[name];
});
var result = fn.apply(context, paramValues);
return result;
};
Injector.prototype.registerBindings = function (bindingDictionary) {
this._bindingDictionary = bindingDictionary;
this._bindings = bindingDictionary.getBindings();
};
Injector.prototype.create = function (targetPath) {
if (!this._bindings) {
throw 'Cannot call method generate before bindings were registered. Use [injector].registerBindings([bindings])';
}
var cwd = process.cwd();
var bindingValues = this._bindings[targetPath];
var rawModule = require(cwd + '/' + targetPath);
var instantiate = bindingValues && bindingValues.toInstantiate && bindingValues.toInstantiate.indexOf(targetPath) != -1;
if (!bindingValues || !bindingValues.dependencies) {
if (instantiate) {
return new rawModule();
}
return rawModule;
}
var dependencies = bindingValues.dependencies.map((function (dep) {
var createdModule = this.create(dep);
var instantiateDependency = bindingValues && bindingValues.toInstantiate && bindingValues.toInstantiate.indexOf(dep) != -1;
if (instantiateDependency && typeof createdModule == 'function') {
return new createdModule();
}
return createdModule;
}).bind(this));
var constructor = this.createConstructor(rawModule, dependencies);
if (instantiate) {
console.log('instantiating ' + targetPath);
return new constructor();
}
console.log('not instantiating ' + targetPath);
return constructor;
};
// #endregion
// #region private methods
Injector.prototype._getParameterNames = function (func) {
var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg,
ARGUMENT_NAMES = /([^\s,]+)/g;
var fnStr = func.toString().replace(STRIP_COMMENTS, ''),
result = fnStr.slice(fnStr.indexOf('(') + 1, fnStr.indexOf(')')).match(ARGUMENT_NAMES);
if (result === null) {
result = [];
}
return result;
};
// #endregion
module.exports = Injector;