node-di: a dependency injection framework for node.js
Uncle Bob is a proponent of inversion of control to counter what he defines as "bad design":
There is one set of criteria that I think all engineers will agree with. A piece of software that fulfills its requirements and yet exhibits any or all of the following three traits has a bad design. 1. It is hard to change because every change affects too many other parts of the system. (Rigidity) 2. When you make a change, unexpected parts of the system break. (Fragility) 3. It is hard to reuse in another application because it cannot be disentangled from the current application. (Immobility) ... What is it that makes a design rigid, fragile and immobile? It is the interdependence of the modules within that design.
One solution to standardise the interfaces of modules (or classes) is dependency injection. Vojta Jina has put together a powerful, lightweight dependency injection library for node.js. Its example is testament to its simplicity:
var Car = function(engine) { this.start = function() { engine.start(); }; }; var createPetrolEngine = function(power) { return { start: function() { console.log('Starting engine with ' + power + 'hp'); } }; }; // a module is just a plain JavaScript object // it is a recipe for the injector, how to instantiate stuff var module = { // if an object asks for 'car', the injector will call // new Car(...) to produce it 'car': ['type', Car], // if an object asks for 'engine', the injector will call // createPetrolEngine(...) to produce it 'engine': ['factory', createPetrolEngine], // if an object asks for 'power', the injector will give it number 1184 'power': ['value', 1184] // probably Bugatti Veyron }; var di = require('di'); var injector = new di.Injector([module]); injector.invoke(function(car) { car.start(); });
Martin Fowler has more to say on the benefits of Dependency Injection.