@kapitchi/bb-dic

A dependency injection container with async support.

Downloads in past

Stats

StarsIssuesVersionUpdatedCreatedSize
@kapitchi/bb-dic
1.8.15 years ago7 years agoMinified + gzip package size for @kapitchi/bb-dic in KB

Readme

bb-dic
Build Status
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 flag

Koa

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