JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 273723
  • Score
    100M100P100Q177022F
  • License Apache-2.0

Dependency injection for Typescript

Package Exports

  • typedi
  • typedi/Container

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (typedi) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

TypeDI

Dependency injection tool for Typescript.

Installation

  1. Install module:

    npm install typedi --save

  2. Use typings to install all required definition dependencies.

    typings install

  3. ES6 features are used, so you may want to install es6-shim too. You also need to install reflect-metadata package.

    npm install es6-shim --save npm install reflect-metadata --save

    if you are building nodejs app, you may want to require("es6-shim"); and require("reflect-metadata") in your app.

Usage

If you simply want to use a container:

import {Container} from "typedi";

class SomeClass {

    someMethod() {
    }

}

let someClass = Container.get(SomeClass);
someClass.someMethod();

If you want to inject other classes into your service you can do:

import {Container, Inject} from "typedi";

class BeanFactory {
    create() {
    }
}

class SugarFactory {
    create() {
    }
}

class WaterFactory {
    create() {
    }
}

class CoffeeMaker {

    @Inject()
    beanFactory: BeanFactory;
    
    @Inject()
    sugarFactory: SugarFactory;
    
    @Inject()
    waterFactory: WaterFactory;

    make() {
        this.beanFactory.create();
        this.sugarFactory.create();
        this.waterFactory.create();
    }

}

let coffeeMaker = Container.get(CoffeeMaker);
coffeeMaker.make();

If you want to use constructor injection:

import {Container, Service} from "typedi";

class BeanFactory {
    create() {
    }
}

class SugarFactory {
    create() {
    }
}

class WaterFactory {
    create() {
    }
}

@Service()
class CoffeeMaker {

    private beanFactory: BeanFactory;
    private sugarFactory: SugarFactory;
    private waterFactory: WaterFactory;

    constructor(beanFactory: BeanFactory, sugarFactory: SugarFactory, waterFactory: WaterFactory) {
        this.beanFactory = beanFactory;
        this.sugarFactory = sugarFactory;
        this.waterFactory = waterFactory;
    }

    make() {
        this.beanFactory.create();
        this.sugarFactory.create();
        this.waterFactory.create();
    }

}

let coffeeMaker = Container.get(CoffeeMaker);
coffeeMaker.make();

note: Your classes may not to have @Service decorator to use it with Container, however its recommended to add @Service decorator to all classes you are using with container, especially if you class injects other services

Extra feature: Injecting third-party dependencies (experimental)

Also you can inject a modules that you want to require:

import {Container, Service, Require} from "typedi";

@Service()
class CoffeeMaker {

    private gulp: any; // you can use type if you have definition for this package

    constructor(@Require("gulp") gulp: any) {
        this.gulp = gulp; // the same if you do this.gulp = require("gulp")
    }

    make() {
        console.log(this.gulp); // here you get console.logged gulp package =)
    }
}

let coffeeMaker = Container.get(CoffeeMaker);
coffeeMaker.make();

Named services

You can use a named services. In this case you can use interface-based services.

import {Container, Service, Inject} from "typedi";

interface Factory {
    create(): void;
}

@Service("bean.factory")
class BeanFactory implements Factory {
    create() {
    }
}

@Service("sugar.factory")
class SugarFactory implements Factory {
    create() {
    }
}

@Service("water.factory")
class WaterFactory implements Factory {
    create() {
    }
}

@Service("coffee.maker")
class CoffeeMaker {

    beanFactory: Factory;
    sugarFactory: Factory;

    @Inject("water.factory")
    waterFactory: Factory;

    constructor(@Inject("bean.factory") beanFactory: BeanFactory,
                @Inject("sugar.factory") sugarFactory: SugarFactory) {
        this.beanFactory = beanFactory;
        this.sugarFactory = sugarFactory;
    }

    make() {
        this.beanFactory.create();
        this.sugarFactory.create();
        this.waterFactory.create();
    }

}

let coffeeMaker = Container.get<CoffeeMaker>("coffee.maker");
coffeeMaker.make();

Providing values to the container

If you are writing unit tests for you class, you may want to provide fakes to your classes. You can use set or provide methods of the container:

Container.set(CoffeeMaker, new FakeCoffeeMaker());

// or alternatively:

Container.provide([
    { name: "bean.factory", type: BeanFactory, value: new FakeBeanFactory() },
    { name: "sugar.factory", type: SugarFactory, value: new FakeSugarFactory() },
    { name: "water.factory", type: WaterFactory, value: new FakeWaterFactory() }
]);

Samples

Take a look on samples in ./sample for more examples of usages.