Skip to content

Instantly share code, notes, and snippets.

@jdpedrie
Last active August 29, 2015 14:09
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jdpedrie/0043ee41b8bb4460223a to your computer and use it in GitHub Desktop.
Save jdpedrie/0043ee41b8bb4460223a to your computer and use it in GitHub Desktop.
Angular-style Dependency Injection!
var di = function() {
var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
var ARGUMENT_NAMES = /([^\s,]+)/g;
var deps = {};
var getParamNames = function(func) {
var fnStr = func.toString().replace(STRIP_COMMENTS, '');
var result = fnStr.slice(fnStr.indexOf('(')+1, fnStr.indexOf(')')).match(ARGUMENT_NAMES);
if(result === null) {
result = [];
}
return result;
};
var invoke = function(dep) {
var params = [];
getParamNames(dep).forEach(function(paramName) {
params.push(this.get(paramName));
}, this);
return dep.apply(window, params);
};
function diError(message) {
this.name = 'diError';
this.message = message;
}
diError.prototype = new Error();
diError.prototype.constructor = diError;
return {
/**
* Add a service to the dependency injector.
* value is usually a function. If value is anything other than a function, invoke MUST be false.
* If invoke is true or undefined, value is invoked before being injected.
* @param string key
* @param mixed value
* @param bool invoke
*/
add: function(key, value, invoke) {
invoke = (typeof invoke === 'undefined') ? true : invoke;
if (!!invoke && typeof value !== 'function') {
throw new diError('value is not a function');
}
deps[key] = {
value: value,
invoke: !!invoke
};
},
/**
* Add a value to the dependency injector.
* Essentially a shortcut for add('key', 'val', false);
* These are never invokable.
* @param string key
* @param mixed value
*/
value: function(key, value) {
return this.add(key, value, false);
},
/**
* Fetch a value from the dependency injector.
* If it is invokable, it will try to resolve any dependencies the value asks for.
* @param string key
*/
get: function(key) {
if (typeof deps[key] === 'undefined') {
throw new diError('Dependency `'+ key +'` is not defined');
}
var dep = deps[key];
if (dep.invoke && typeof dep.value !== 'function') {
throw new diError('Cannot invoke dependency because dependency is not a function!');
}
return (dep.invoke) ? invoke.call(this, dep.value) : dep.value;
}
};
};
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Dependency Injection Example</title>
</head>
<body>
<h1 id="greeting"></h1>
<script src="di.js"></script>
<script>
var app = di();
app.add('myCtrl', function(DOMGuy, greeting) {
DOMGuy.updateElementValue('greeting', greeting);
});
app.add('DOMGuy', function() {
return {
updateElementValue: function(id, value) {
document.getElementById(id).innerHTML = value;
}
};
});
app.value('greeting', 'Hello Worldzzz!', false);
app.get('myCtrl');
</script>
</body>
</html>
@jdpedrie
Copy link
Author

Expected result:

Hello Worldzzz!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment