Skip to content

Instantly share code, notes, and snippets.

@torgeir
Created September 11, 2012 11:50
Show Gist options
  • Select an option

  • Save torgeir/3697840 to your computer and use it in GitHub Desktop.

Select an option

Save torgeir/3697840 to your computer and use it in GitHub Desktop.
Poor mans JavaScript dependency injection
(function () {
(typeof window == 'undefined' ? global : window).ioc = ioc;
var singletons = {};
function ioc (Constructor, previous) {
if ((previous || (previous = [])).indexOf(Constructor) != -1) {
throw new Error('circular!');
}
else {
previous.push(Constructor);
}
var instances = [];
foreach(dependencyOf(Constructor), function (Dependency) {
var dependency;
if (Dependency.length) {
dependency = ioc(Dependency, previous);
}
else {
dependency = singletons[Dependency.toString()] || new Dependency();
}
instances.push(dependency);
});
return create(Constructor, instances);
}
ioc.singleton = function (Constructor) {
if (typeof Constructor === 'object') {
singletons[Constructor.constructor.toString()] = Constructor;
return;
}
singletons[Constructor.toString()] = new Constructor();
};
function dependencyOf (Constructor) {
return map(parametersOf(Constructor.toString()), function (parameter) {
var DependencyName = capitalize(parameter);
try {
var Dependency = eval(DependencyName);
return Dependency;
}
catch (e) {
throw new Error('No type ' + DependencyName + ' in scope, ' +
'which is a dependency of ' + Constructor +
'\n' + e);
}
});
}
var PARAMETERS_REGEX = /\((.*?)\)/;
function parametersOf (constructorString) {
var matches = constructorString.match(PARAMETERS_REGEX);
return matches[1] && matches[1].replace(/ /g, '').split(',') || [];
}
function capitalize (string) {
return string[0].toUpperCase() + string.slice(1);
}
function create (Klass, args) {
function F () {}
F.prototype = Klass;
var instance = new F();
Klass.apply(instance, args);
return instance;
}
function map (array, fn) {
var result = [];
foreach(array, function (el) { result.push(fn(el)); });
return result;
}
function foreach (array, fn) {
for (var i = 0; i < array.length; i++) fn(array[i]);
}
})();
/* example */
function Service () {
this.name = 'the service';
}
var i = 0;
function Messages () {
this.welcome = 'hello from messages #' + i++;
}
/* singleton Messages */
//ioc.singleton(Messages);
/* or, use a specific instance for all Messages */
//var messages = new Messages();
//messages.welcome = 'hello there!';
//ioc.singleton(messages);
function Controller (messages, service) {
this.service = service;
this.messages = messages;
}
function AnotherController (messages, service) {
this.service = service;
this.messages = messages;
}
console.log(ioc(Controller));
console.log(ioc(AnotherController));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment