zack.di

Dependency Injection for JavaScript


License
MIT
Install
npm install zack.di@0.1.0

Documentation

zack.di Build Status Coverage Status

Dependency Injection for JavaScript

  • Simple: zack.di's container is inspired by the simple API of Pimple, easy to use and powerfull.
  • Decorators: zack.di's decorators can be used to easily register and inject services.

Installation

$ npm install zack.di

The npm package provides a CommonJS build for use in Node.js, and with bundlers like Webpack and Browserify. To be able to use decorators now, you can use Babel and the decorator transform plugin to transform them to current versions of JavaScript.

Container

container.set(serviceId, definition | value)

import container from 'zack.di';

// Use a factory to lazy load a dependency …
container.set('my.service', () => {
  const config = container.get('my.service.config');
  
  return new MyService(config);
});

// … or add simple values like objects, booleans, strings or numbers.
container.set('my.service.config', {
  //
});

Adds a definition to initialize a service or primitive values (like numbers, strings, objects or booleans) to the container.

container.get(serviceId)

import container from 'zack.di';

// A service instance …
const service = container.get('my.service');
// … and a configuration from the previous code example.
const config = container.get('my.service.config');
 
console.log(service === container.get('my.service')); // true

Retrieves services by the given identifier and lazy-loads them. Keep in mind, that this method always returns the same instance unless you use service.factory().

container.has(serviceId)

import container from 'zack.di';

console.log(container.has('my.service')); // true

Return true or false whether or not the container has a service with the given ID.

service.factory()

import container from 'zack.di';

// Use a factory to lazy load a dependency …
container
  .set('my.factory', () => {
    const config = container.get('my.service.config');
    
    return new MyFactoryService(config);
  })
  .factory();

console.log(container.get('my.factory') === container.get('my.factory')); // false

By default each time you retrieve a service, the container returns the same value. factory can be used to create new service instances every time get is called.

service.tag(...names)

import container from 'zack.di';

// Use a factory to lazy load a dependency …
container
  .set('my.tagged.service', () => {
    const config = container.get('my.service.config');
    
    return new MyFactoryService(config);
  })
  .tag('my.tag');

container
  .set('my.tagged.value', true)
  .tag('my.tag');

console.log(container.tagged('my.tag')); // Array with an instance of my.tagged.service and true from the my.tagged.value

With tag you are to one or more tags to your services. This is useful to group and retrieve certain types of services like plugins, listeners, etc.

service.extend(serviceId, extension)

import container from 'zack.di';

container.service('my.service')
  .extend((myService) => {
    myService.callFancyMethod();
      
    return myService;
  });

By using extend it's also possible to extend a previous defined service to replace, extend or further initialise it. extension must be a function taking the original service and returning the extended one.

Decorators

service(serviceId)

import container, { service } from 'zack.di';

@service('my.service')
class MyService {
  //
}

console.log(container.get('my.service')); // Instance of MyService

Decorates a class as a service.

inject(...serviceIds)

import container, { service, inject } from 'zack.di';

@service('my.service')
@inject('my.bar_service', 'my.blub_service')
class MyService {
  @inject('my.foo_service')
  foo;
  
  constructor(bar, blub) {
    this.bar = bar;
    this.blub = blub;
  }
}

const service = container.get('my.service');

console.log(service.foo, service.bar, service.blub); // Instance of my.foo_service, my.bar_service and my.blub_service

Injects one ore more services into the class constructor or class properties when initialized.

tag(...names)

import container, { service, inject } from 'zack.di';

@service('my.service')
@tag('my.first_tag', 'my.second_tag')
class MyService {
  //
}

Tags a services with one or more tags. This is useful to group and retrieve certain types of services like plugins, listeners, etc.

Custom Container

Container and decorators(container)

import Container from 'zack.di/dist/Container';
import decorators from 'zack.di/dist/decorators';

const container = new Container();
const { service, inject } = decorators(container);

If you don't want to use the default container you can use the Container class and decorators function to create your own container and service decorators.