bb-dic
A dependency injection container with async support.
Installation
npm install @kapitchi/bb-dic
Usage
For ES5/ES6 compatible implementation use require('@kapitchi/bb-dic/es5')
.DIC uses acorn to parse the code to discover function parameters.
If you encounter parsing issues try to fiddle with
ecmaVersion
parameter (default 8).See
examples
folder for full usage examples.Framework usage examples can be found at the bottom.
Sync usage
class MyService {
constructor(myServiceOpts) {
this.options = myServiceOpts;
}
showOff() {
console.log('My options are:', this.options);
}
}
const {Dic} = require('@kapitchi/bb-dic');
const dic = new Dic();
// register all instances
dic.instance('myServiceOpts', { some: 'thing' });
dic.class('myService', MyService);
dic.factory('myApp', function(myService) {
return function() {
// some application code
myService.showOff();
}
});
// use it
const app = dic.get('myApp');
app();
Async usage
Use when one of your class instances or instance factories needs async initialization.const {Dic} = require('@kapitchi/bb-dic');
const dic = new Dic();
class AsyncService {
async asyncInit() {
// some async await calls
}
showOff() {
console.log('Perfect, all works!');
}
}
dic.class('asyncService', AsyncService);
dic.asyncFactory('asyncMsg', async function() {
// some async calls needed to create an instance of this service
return 'Async helps the server.';
})
dic.factory('myApp', function(asyncService, asyncMsg) {
return function() {
// some application code with all services ready
myService.showOff();
console.log(asyncMsg);
}
});
// Creates myApp service and instantiate all its direct dependencies
dic.getAsync('myApp').then(app => {
app();
});
API
{{>main}}Framework usage examples
Run on NodeJS 7. with --harmony
flagKoa
const Koa = require('koa');
const {Dic} = require('@kapitchi/bb-dic');
const dic = new Dic();
dic.instance('functionMiddlewareOpts', { returnString: 'Hello World' });
dic.factory('functionMiddleware', function(functionMiddlewareOpts) {
return async (ctx) => {
console.log('functionMiddleware > before');//XXX
ctx.body = functionMiddlewareOpts.returnString;
console.log('functionMiddleware > after');//XXX
}
});
dic.class('classMiddleware', class ClassMiddleware {
async asyncInit() {
// some async initialization
}
async middlewareOne(ctx, next) {
console.log('classMiddleware.middlewareOne > before');//XXX
await next();
console.log('classMiddleware.middlewareOne > after');//XXX
}
});
dic.factory('app', function(
classMiddleware,
functionMiddleware
) {
const app = new Koa();
app.use(classMiddleware.middlewareOne);
app.use(functionMiddleware);
return app;
});
(async () => {
const app = await dic.getAsync('app');
app.listen(3000);
console.log('Running at: http://localhost:3000');
})();
Hapi
const Hapi = require('hapi');
const {Dic} = require('@kapitchi/bb-dic');
const dic = new Dic();
dic.instance('functionHandlerOpts', {
response: {
msg: 'Hello from function handler'
}
});
dic.instance('classHandlerOpts', {
response: {
msg: 'Hello from class handler'
}
});
dic.factory('functionHandler', function (functionHandlerOpts) {
return async (request, reply) => {
reply(functionHandlerOpts.response);
}
});
dic.class('classHandler', class ClassHandler {
constructor(classHandlerOpts) {
this.options = classHandlerOpts;
}
async asyncInit() {
// some async initialization
}
async handler(request, reply) {
reply(this.options.response);
}
});
dic.factory('server', function(
functionHandler,
classHandler
) {
const server = new Hapi.Server();
server.register([
require('hapi-async-handler')
], function(err) {
if (err) {
throw err;
}
});
server.connection({
host: 'localhost',
port: 8000
});
server.route({
method: 'GET',
path: '/func',
handler: functionHandler
});
server.route({
method: 'GET',
path: '/class',
handler: classHandler.handler.bind(classHandler)
});
return server;
});
(async () => {
server = await dic.getAsync('server');
await server.start();
console.log('Server running at:', server.info.uri);
})();
Development
Run the command below to builds es5 folder and README.md.npm run build
Tests
npm test
Contribute
Please feel free to submit an issue/PR or contact me at matus.zeman@gmail.com.License
MIT