magnum-di

A super simple Scoped Dependency Injection framework for NodeJS

Usage no npm install needed!

<script type="module">
  import magnumDi from 'https://cdn.skypack.dev/magnum-di';
</script>

README

Magnum DI

A super simple Scoped 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.createChild() ⇒ MagnumDI

Creates a Child instance of the current injector. Calls to .get or .inject will first search this injector, if a parameter is found it will return it if not it will continue up the tree until a value is found or the topmost instance is reached.

Kind: instance method of MagnumDI

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