epoxy-di
v0.1.6
Published
Elegant, seamless dependency injection container for node.js
Downloads
4
Readme
epoxy
Epoxy is a lightweight (~200 sloc) IoC container for NodeJS. Notable features:
- automatic dependency injection ( in multiple flavours )
- multiple injection patterns -
constant, constructor, factory, singleton
- circular depedency detection and resolution
- made with 💜 and ES2015
Installation
npm install epoxy-di
Table of Contents
Basic Usage
// ./index.js
const { Container, Providers } = require( 'epoxy-di' )
const ioc = new Container( [
Providers.CurrentDirectory,
Providers.NodeModules
] )
ioc.create( 'app' )
// ./app.js
exports = module.exports = (
http,
router = 'handlers/router'
) => {
return http.createServer( router )
}
// ./handlers/router
exports = module.exports = (
index = 'handlers/index',
notFound = 'handlers/404'
) => ( req, res ) => {
switch( req.url ) {
case '/':
case '/index':
return index( req, res )
default:
return notFound( req, res )
}
}
API
Container
constructor( [ providers = Providers.CurrentDirectory ] )
The Container
constructor accepts a list of providers. If none are provided, it will default to the current directory provider.
Container.create( id )
Creates the module with the given id. Resolves dependencies automatically and caches factories and instances along the way.
Container.provide( path )
Adds providers after container creation.
Container.register( id, factory )
Registers a factory for the provided id with the container. Useful for mocking out modules or providing overrides.
Providers
Providers are sources ( paths at the moment ) where to look for dependencies when resolving modules. Providers are relative to the file where create is called.
There are two predefined providers shipped with epoxy:
CurrentDirectory
- provides modules in the current directory ( default )
NodeModules
- provides node modules
Strategies
There are multiple strategies provided for dependency discovery and type definition for a module:
Exports
exports = module.exports = ( http, handler, port ) => {
return class {
constructor( ) {
this.server = http.createServer( a )
}
}
}
exports[ '@type' ] = 'constructor'
exports[ '@inject' ] = [
'http',
'middleware/handler',
'config/port'
]
Parse (default)
exports = module.exports = (
http,
handler = 'middleware/handler',
port = 'config/port'
) => {
return class {
constructor( ) {
this.server = http.createServer( a )
}
}
}
exports[ '@type' ] = 'constructor'
Types
Multiple injection types are supported:
Constant
- module injected as-is, and cached
Constructor
- module treated as a constructible, injected with new
Factory
- module treated as a factory; injection is done by calling the factory each time to get a fresh instance
Singleton
- same as Factory
, but the first resulting instance is cached and injected for all subsequent times
Circular dependency
Circular dependencies are allowed and will be resolved ( with the help of lazyref ), but generally if you come to a situation where you have a circular dependency in your project it is likely that you have a design flaw that you can correct rather than keep a cicular dependency.
Next on my list
- [ ] async modules
- [ ] performance benchmarks
- [ ] more robust depedency parsing
License
MIT