At first, great job. This DI framework is really great.
But while working with angular, i really like to simply require a dependency by just naming the parameter correctly.
Example:
module.exports = function TimeAlarm(moment) { // Lets roll }
This removes the "@require" annotation.
Maybe my attempt is already helpful:
To get the parameter of a function, i copied the auto-annotation function from angular's di code:
function isArray(arr){
return typeof arr.length != "undefined"
}
var FN_ARGS = /^function\s*[^\(]*\(\s*([^\)]*)\)/m;
var FN_ARG_SPLIT = /,/;
var FN_ARG = /^\s*(_?)(\S+?)\1\s*$/;
var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
function annotate(fn) {
var $inject,
fnText,
argDecl,
last;
if (typeof fn == 'function') {
if (!($inject = fn.$inject)) {
$inject = [];
if (fn.length) {
fnText = fn.toString().replace(STRIP_COMMENTS, '');
argDecl = fnText.match(FN_ARGS);
argDecl[1].split(FN_ARG_SPLIT).forEach(function (arg) {
arg.replace(FN_ARG, function (all, underscore, name) {
$inject.push(name);
});
});
}
fn.$inject = $inject;
}
} else if (isArray(fn)) {
last = fn.length - 1;
// assertArgFn(fn[last], 'fn');
$inject = fn.slice(0, last);
} else {
// assertArgFn(fn, 'fn', true);
}
return $inject;
}
This will simply give an array of the parameter names of passed function.
Example from the code:
Container.prototype._registerModule = function(id, mod, sid) {
var dependencies = mod['@require'] || []
, pattern = 'literal';
if(typeof mod != "undefined" && (!mod['@require'])) {
//Will print ["moment"] for the TimeAlarm component
console.log(annotate(mod));
dependencies = annotate(mod);
}
if (typeof mod == 'function') { [...]
(container.js:235)
I did some changes, but i get stuck when my application uses paths to reach the components.
I changed the registering function:
Container.prototype.register = function(comp, sid) {
// TODO: Pass sid to constructor (??)
comp._sid = sid;
//This will register components defined with paths as well
//Example: "utils/Logger" will be available under "utils/Logger" and just "Logger"
var arrSplitPath = comp.id.split("/");
if(typeof this._o[arrSplitPath[arrSplitPath.length-1]] != "undefined"){
this._o[arrSplitPath[arrSplitPath.length-1]] = comp;
}
this._o[comp.id] = comp;
}
(container.js:132)
With this change, my annotation will inject 'Logger' correctly.
But when i use ioc.node, the application cant find the components.
The required components is under "components/alarm/AlarmManager"
I will require "AlarmManager" by auto-annotation.
It will call the function Container.prototype._loadModule
And there it fails, because i cant simply search within source.fn of each node, since it will try to load the script with scripts.resolve directly.
At first, great job. This DI framework is really great.
But while working with angular, i really like to simply require a dependency by just naming the parameter correctly.
Example:
module.exports = function TimeAlarm(moment) { // Lets roll }
This removes the "@require" annotation.
Maybe my attempt is already helpful:
To get the parameter of a function, i copied the auto-annotation function from angular's di code:
This will simply give an array of the parameter names of passed function.
Example from the code:
(container.js:235)
I did some changes, but i get stuck when my application uses paths to reach the components.
I changed the registering function:
(container.js:132)
With this change, my annotation will inject 'Logger' correctly.
But when i use
ioc.node
, the application cant find the components.Example: In my code i've got something like this:
The required components is under "components/alarm/AlarmManager"
I will require "AlarmManager" by auto-annotation.
It will call the function
Container.prototype._loadModule
And there it fails, because i cant simply search withinsource.fn
of each node, since it will try to load the script withscripts.resolve
directly.