Node dependency injection library extracted from DecentCMS
There are quite a few DI libraries for Node, I know, and I evaluated many of them before building my own. It’s not that the others are bad, it’s just that I needed a few unique features that I couldn’t find together in a single library. My library, Decent Injection, is exactly what I needed for DecentCMS, because it was built as its foundation, with no other requirement than to be useful to me. My goal by extracting it as its own project is to help those users who have told me that they would like to use it in their own projects. Often, when building exactly the library you need, you end up with something that others will find useful too. It’s pretty cool when it happens.
So what is that unique set of requirements that Decent Injection satisfies?
- Handle hierarchies of scopes that each manage a different service lifetime. For example, in DecentCMS, some services must remain active as long as the site is up, and then some others only live for the duration of the request, and are uniquely associated with that request and its state. Services can specify what scope level they should be associated with. The DI library can then manage the lifetime of those services, without the client code having to know or do anything about it. Just require the service you need, and use it; it will get disposed at the proper time.
- Mix-in the scope concept on existing objects. A great example of this is the request object in DecentCMS: Node or Express creates the request object and hands it to the DecentCMS middleware. The request happens to be one of the most commonly used scopes in the system, and it’s easy with Decent Injection to just make it behave like a scope as needed.
shell.makeSubScope('request', req);
It’s less confusing, and leads to code that’s more expressive, to just mix the new behavior into the existing request object, than it would be to hang a “requestScope” object to it. - Enable multiple implementation of a service. Shape handlers, for example, which are services responsible for handling plain JavaScript objects and preparing them for rendering by a template, are all implementations of the `shape-handler` service. It is easy with Decent Injection to asynchronously call all implementations of a method of a service:
scope.callService('shape-handler', 'handle', context, function done(err) {...});
Of course, it also satisfies some more common requirements. For example, injection can be done following a constructor injection pattern, a property injection pattern, or a service locator pattern.
You can learn more about Decent Injection from its documentation:
https://www.npmjs.com/package/decent-injection
And also from its API documentation:
https://github.com/DecentCMS/DecentInjection/blob/master/doc/scope-api.md
When I started writing DecentCMS, one of my goals was to make it easy for application developers to adopt only the bits and pieces that they need into their existing or new applications. The release of Decent Injection is part of this. Next, I’ll also release the service discovery code and the multi-tenancy library as separate NPM modules, to help application developers build modular and multi-tenant applications, without necessarily buying into the whole of DecentCMS.