Inversion Of Control & Dependency Injection With Node.js ~ Sat, 27 Dec 2014 19:00:28 +0000
A Google+ discussion has led me to write this post. In the discussion the question of whether traditional Node.js modules are better than using an Inversion of Control (IoC) container and the Dependency Injection (DI) pattern.
If you've written, or reviewed, any sizable project in Node.js then you've surely seen code like the following:
var foo = require('../some/parent/dir/foo');
// ...
// ...
If you're project is small, say two or three files, this works well. Refactoring isn't a problem since the changes will be few. But any larger than that, and refactoring becomes a chore. Okay, so maybe refactoring isn't that big of an issue. What if you're a proponent of test driven development? Chances are you want to test individual components separate from their dependencies. With the above method of importing dependencies that sort of separation is very difficult if not impossible during testing.
"Well duh, you should be separating those things out into modules" you say. Sure, that works for stuff like a random picker module, a wrapper for a third party service, or your own templating mechanism. But the core domain of your application is specific to the application. It doesn't make sense to break it out into separate modules. The same is true of the controllers, services, and so on.
That's where IoC and DI shine. And Node.js has a very easy to use IoC and DI library in Electrolyte. Electrolyte allows you to decouple your dependencies from the file system (at least much better, anyway) while still utilizing the traditional Node.js require
function and module pattern.
An example of using Electrolyte to solve this problem is too involved for this post. So I wrote a sample project. The project shows the two ways in which Electrolyte can be used:
- As a simple hash of component locations and a component loader
- As an automatic dependency injector
Give the project a read. I think you'll find that DI actually cleans up the code, makes it much more robust, and easier to maintain.