di-linker
is a lightweight Dependency Injection for Javascript.
It provides some main features:
- No more hard-coded dependencies
- No more confusing
require
statement - Scan source codes, wire them together then bootstrap main module
- Work both in server and client
npm install di-linker
Prepare source codes:
// index.js
var di = require('di-linker');
var sources = [
'app/**/*.js'
];
di.walk(sources, require).then(function(context) {
return context.bootstrap(['/main']); // entry point
}).catch(console.error.bind(console))
// app/main.js
exports.name = '/main';
exports.requires = [
'/lib' // wire `/lib` module
];
exports.factory = function(lib) {
// use `lib` here
console.log('`lib` module injected');
};
// app/lib.js
exports.name = '/lib';
exports.requires = [
'@fs', // require `fs` package
'@path' // require `path` package
];
exports.factory = function(fs, path) {
return {
fs: fs,
path: path
};
};
That is all, now you can run your application:
node ./index.js
exports.name
{String} Define module nameexports.requires
{Array} Define the module's dependencies. Note that@
prefix means requiring Node packagesexports.factory
{Function} Define a function as factory for the module. Module's dependencies are injected as parameters of this functionexports.activations
{Array} List of other modules need be activated after the module initialized (can be omitted)exports.value
{Object} Use a specified value insteads of factory. This option will overridefactory
option
bower install di-linker
In HTML:
<script src="bower_components/di-linker/dist/di-linker.standalone.min.js"></script>
In Javascript:
var context = __('app_name');
context.factory('main', [
'lib',
function(lib) {
// lib is injected and can be used here
}
]);
context.factory('lib', [
function() {
return {
veryUsefulFunction: function() {}
};
}
]);
context.bootstrap(['main']);
Because di-linker
use lodash
and bluebird
internally, so those modules are built-in. They can be injected via reversed words @lodash
and @bluebird
.
__('app_name').factory('lib', [
'@lodash',
'@bluebird',
function(_, Promise) {
}
]);
Context
is core class of di-linker
. It can be created by the following methods:
Server-side:
var di = require('di-linker');
// scan code folder and return a context instance via promise
di.walk(patterns).then(function(context) {
});
// another way
var newContext = di('context_name');
var sameContext = di('context_name');
var anotherConctext = di('another_context_name');
console.log(newContext === sameContext); // true
console.log(newContext === anotherContext); // false
// another way
var context = new di.Context();
Client-side:
// get a context instance via global function `__`
var newContext = __('context_name');
var sameContext = __('context_name');
var anotherConctext = __('another_context_name');
console.log(newContext === sameContext); // true
console.log(newContext === anotherContext); // false
// another way
var context = new __.Context();
def
{Object}name
{String} Define module namerequires
{Array} Define the module's dependencies. Note that@
prefix means requiring Node packagesactivations
{Array} List of other modules need be activated after the module initialized (can be omitted)factory
{Function} Define a function as factory for the module. Module's dependencies are injected as parameters of this functionvalue
{Object} Use a specified value insteads of factory. This option will overridefactory
option
- return: current context
Register a dependency
name
{String} Dependency namevalue
{Object} Dependency value, will be injected- return: current context
Sugar method of context.register()
for value-type dependency, with name
and value
only
name
{String} Dependency namedef
{Array} Last element is factory function, other are name of dependencies need to injected- return: current context
Sugar method of context.register()
for factory-type dependency, width name
, requires
and factory
only
modules
{Array} Array of module name that need to execute- return: a promise that resolve the current context when bootstrap is done
Execute some modules that registered already in the context
preferences
{Object} Key-value map of the preferencesverboseLog
{Boolean} Enable verbose log for resolving and resolved statesallowReRegister
{Boolean} Allow to re-register existing module. Only use this option for mocking dependencies in testing
- return: current context
$ npm install
$ npm test