q-injector
v1.0.1
Published
Lightweight asynchronous promise-based dependency injector
Downloads
2
Readme
Q injector
Lightweight asynchronous promise-based dependency injector (60 lines of code).
npm install q-injector
About
Dependency injector for Node.js based on Q, inspired by angular.js injector, supporting asynchronous dependency initialization with Promise/A+ style API.
Usage
var Injector = require('q-injector'),
app = new Injector(); // create application based on the Injector
// register dependency `service1` within the injector
app.instance('service1', {
method1: function () { /* ... */ },
// ...
});
// register a factory method of dependency `service2`
app.instance('service2', function (service3) { // inject `service3` into the factory method
return { /* ... */ };
});
// register an asynchronous factory method for `service3`
app.instance('service3', function () {
// ...
return thenable; // returns promise, that will be resolved
// during injection of `service3` into `service2`
});
// initiates dependency initialization and injects initialized dependencies
app.invoke(function (service1, service2) {
// at this point all services are resolved,
// `service3` is injected into `service2` factory method
service1.method1();
// ...
});
// another method to inject a dependency
app.get('service1').then(function (service1) {
service1.method1();
// ...
});
Terms
Dependency
Dependency is an object used by other objects. A dependency have a name, used by other objects to refer to the dependency.
In terms of JavaScript, dependency can be a function, an object, a number, anything.
Factory method
A JavaScript function, used to construct a dependency object. It can be asynchronous, returning a promise.
Dependency injection
Dependency injection is a process of dependency resolution. Objects get links to their dependencies declared by names.
An Injector instance has a single namespace for dependencies. Dependency named
service1
will be always the same within the Injector instance.
One dependency can depend on other, others can depend on another, etc. By
calling injector.factory()
you define dependency graph which will be
resolved during injection, when you call injector.invoke()
or
injector.get()
.
API
injector.instance(name, obj)
Register an object obj
as dependency named name
.
injector.factory(name, factory, [locals])
Register a factory method factory
which will be used to construct a
dependency named name
. Factory method factory
won't be invoked until
dependency name
is requested to be injected into another object. factory
will be invoked using injector.invoke()
method, which means that factory
method may have dependencies as well.
Factory method is called only once and its return value is cached in the Injector instance.
factory
may return a plain object or a promise, which will be resolved before
being injected into another object.
Optional locals
is an override of dependencies injected into the factory
.
For example:
app.factory('service1', function (service2, service3) {
service2 == 's2' // true
// service3 is previously registered dependency
}, {
service2: 's2'
});
injector.get(name)
Resolve previously registered dependency by name
and return a promise.
For example:
app.get('service1').then(function (s1) {
// ...
});
injector.invoke(fn, [locals])
Parse fn
function declaration argument names, resolve previously registered
dependencies by their names and invoke fn
with the dependecies.
Returns a promise which will be resolved to a return value of fn
.
Optional locals
is an override of dependencies injected into fn
.
For example:
app.invoke(function (service1, service2) {
service2 == 's2' // true
// service1 is previously registered dependency
return 'hello';
}, {
service2: 's2'
}).then(function (ret) {
ret == 'hello' // true
});
Tests
If it's not still clear how q-injector works, take a look at provided testsuite. There are all possible use cases.