@kapitchi/bb-dic

A dependency injection container with async support.

Stats

StarsIssuesVersionUpdatedCreatedSize
@kapitchi/bb-dic
431.8.13 years ago4 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

If you find any bugs or have a feature request, please open an issue on github!

The npm package download data comes from npm's download counts api and package details come from npms.io.