Last active
August 29, 2015 14:09
-
-
Save jdpedrie/0043ee41b8bb4460223a to your computer and use it in GitHub Desktop.
Angular-style Dependency Injection!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
}; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Expected result:
Hello Worldzzz!