node package manager
Share your code. npm Orgs help your team discover, share, and reuse code. Create a free org »

magnum-di

Magnum DI

A super simple Key,Value Dependency Injection framework for NodeJS

NPM Version - Seeing this? Shields.io is broken, again. Linux Code Coverage

npm install --save magnum-di
//Load it up./ 
var injector = require('magnum-di')()
 
//Register some dependencies. 
injector.service('MyService', {name: 'Bob', sayName: function(){console.log(this.name)}})
 
//inject them into your function 
injector.inject(function(MyService){
    MyService.sayName() // -> Bob 
})

Why Dependency Injection?

  • Managing complex applications with many files. Maintaining module dependencies in one location reduces errors and makes an application easier to reason about.
  • Procedurally loading files with dependencies becomes much easier.
  • Ease of testing in isolation, mocking module dependencies becomes trivial. No need to use a module to fiddle with the internals of require to get a mocked object into your module. With DI just register a different module with the correct methods and you are done mocking.

Examples

Express route definitions.

Here we register a dependency in our main application file, and use the injector to call the function returned by the require('./UserModel) call.

Run this with npm run example-server

 
//userRoutes.js 
 
module.exports = function(Router, User) {
 
  //Here Router and User will be injected. 
  Router.get('/', function(req, res, next){
    User.userDetails('Bob', function(err, data){
      res.json({user: data})
    })
  });
 
  return {path: '/user', router: Router}
};
 
 
//app.js 
 
var injector = require('magnum-di')();
var express = require('express');
var Database = require('./Database');
var app = express()
var http = require('http');
 
//Register some dependencies. 
injector.factory('Router', express.Router);
injector.service('Database', Database);
 
//Here we are letting the injector provide the database to our UserModel 
//This will make it simple to mock in our unit tests. 
var User = injector.inject(require('./UserModel'));
injector.service('User', User);
 
var userRoute = injector.inject(require('./UserRoutes'));
 
app.use(userRoute.path, userRoute.router);
 
http.createServer(app).listen(8080);

Mocking database for testing

Following our above example, we use magnum-di to mock out our Database object for testing.

Run this with npm run example-test

 
var injector = require('magnum-di');
var should = require('should');
 
//Our mock database object 
injector.service('Database', {
  User: {
    users: {George: {name: 'George', age: 30}, Mike: {name: 'Mike', age: 20}},
    find: function(username, cb) {
     var user = (this.users[username]) ? this.users[username] : null
     cb(null, user);
    }
  }
});
 
//We now have a user model that is using our mock database. 
var User = injector.inject(require('./UserModel'));
 
describe('Model being tested with a mock Database object', function() {
 
  it('should not have real data', function(done) {
    User.userDetails('Bob', function(err, data){
      should(data).be.null
      done()
    })
  });
 
  it('should have mock data', function(done) {
    User.userDetails('George', function(err, data){
      data.age.should.equal(30)
      done()
    })
  });
 
});
 

API

## MagnumDI Kind: global class

### new MagnumDI() Provides an instance of the Magnum DI injector.

### magnumDI.service(name, item) ⇒ * Registers an object, string, number or function.

Kind: instance method of MagnumDI
Returns: * - Returns provided dependency

Param Type Description
name string Name to be used in the injected function
item object | array | number | string | function Item to be injected.

### magnumDI.instance(name, fn) ⇒ function When injected, calls as a constructor with new.

Kind: instance method of MagnumDI
Returns: function - Returns provided function

Param Type Description
name string Name to be used in the injected function.
fn function Function to be called with new.

### magnumDI.factory(name, fn) ⇒ function When injected, calls the passed function. Returns the result of that call.

Kind: instance method of MagnumDI
Returns: function - Retuens provided function.

Param Type Description
name string Name to be used in the injected function
fn function Function to be called by injector.

### magnumDI.merge(name, merge) ⇒ * Merges supplied object into the object registered for , if doesn't exist it will be created.

Kind: instance method of MagnumDI
Returns: * - Returns provided dependency

Param Type Description
name String Dependency object to modify
merge Object Object to merge with existing dependency

### magnumDI.get(name) ⇒ * | null Returns the specified dependency.

Kind: instance method of MagnumDI
Returns: * | null - The named dependency item, or null.

Param Type Description
name string Dependency to retrieve.

### magnumDI.replace(name, replacement) ⇒ Object Modifies a registered service object.

Kind: instance method of MagnumDI
Returns: Object - Replaced dependency

Param Type Description
name String Dependency object to modify.
replacement Object Object to replace current registered object.

### magnumDI.unregister(name) ⇒ boolean Removes the specified dependency.

Kind: instance method of MagnumDI
Returns: boolean - The result of the operation.

Param Type Description
name string Registered dependency to remove.

### magnumDI.inject(fnOrstr, thisArg) ⇒ * Runs the given function with args injected and with an optional context object.

Kind: instance method of MagnumDI
Returns: * - Returns the result of the called function.

Param Type Description
fnOrstr function | string function - inject args and run, string - Return the named dependency.
thisArg object Calling context.

Contributing

Check out, add, document, test.

Run tests with npm test. Regenerate this Readme with npm run readme

licence

MIT