Dependency injection is a software pattern that helps increase the testability of a given class by removing hard coded references to its dependencies.
In other words, take the following code...
function Car() {
this.engine = new Engine();
this.dashboard = new Dashboard();
}
In the preceding code, Car
is now dependent upon Engine
and Dashboard
. This makes it more difficult to unit test the Car
in complete isolation. There's no way to create an
instance of a Car
without in turn creating an instance of an Engine
and a Dashboard
.
Dependency injection allows for a small bit of configuration that says, 'When a class needs a dependency named x, create an instance of y'.
So, you can now have code that would look like...
function Car(engine, dashboard) {
this.engine = engine;
this.dashboard = dashboard;
}
function Engine() {}
function Dashboard() {}
Car = bindr(Car, ['engine', 'dashboard']);
bindr.bind({
"engine": Engine,
"dashboard": Dashboard
});
Now this.engine
will be assigned a new instance of Engine
, and likewise for Dashboard
.
bindr
comes in and allows you to switch a dependencies constructor out. In production code, the Car
might be dependent upon Engine
, but when writing unit tests,
bindr
allows you to swap that dependency out for a FakeEngine
.
var Car = require('Car');
function FakeEngine() {}
function FakeDashboard() {}
describe('when a car is created', function() {
it('should be awesome', function() {
var car = new Car(new FakeEngine(), new FakeDashboard());
});
});
Now you are able to test your Car
in complete isolation.
Another great advantage of Bindr is that it doesn't change your existing functions other than creating a small wrapper. You can simply plug them in your existing constructors, and use them as you normally would.
There is a UMD wrapper around bindr
, so you can either require it as an node, or AMD module, or it will expose bindr
on the window
.
Wraps a constructor for allowing dependency injection.
fn
{function}: the constructor you want to wrapdep
{array}: list of the dependencies of this constructor
Returns a wrapped constructor
Register dependencies with bindr
.
options
{object}: an object containing dependencies
Register a Dependency
to name
.
name
{string}: The name of the dependency to createdependency
{function}: The dependency to inject
Clears all registered dependencies.
Returns an object containing a trace of all dependencies
Returns an object containing a trace of all dependencies for a given instance.
name
{object}: An instance of a function registered withbindr()
This way you can easily swap out the service
dependency of the car
.
Via NPM...
npm install bindr
Via Browser...
<script src="bindr.js"></script>
Via Bower...
bower install bindr --save
Any feedback would be appreciated!