What is typedi?
TypeDI is a dependency injection tool for TypeScript and JavaScript. It allows you to manage the lifecycle and dependencies of your services and components in a clean and efficient way.
What are typedi's main functionalities?
Service Decorator
The `@Service` decorator is used to mark a class as a service that can be injected. The `Container.get` method is then used to retrieve an instance of the service.
```typescript
import { Service } from 'typedi';
@Service()
class ExampleService {
sayHello() {
return 'Hello, World!';
}
}
const exampleService = Container.get(ExampleService);
console.log(exampleService.sayHello()); // Output: Hello, World!
```
Inject Decorator
The `@Inject` decorator is used to inject a dependency into a class. In this example, `DependencyService` is injected into `MainService`.
```typescript
import { Service, Inject } from 'typedi';
@Service()
class DependencyService {
getValue() {
return 'Dependency Value';
}
}
@Service()
class MainService {
constructor(@Inject(() => DependencyService) private dependencyService: DependencyService) {}
getValue() {
return this.dependencyService.getValue();
}
}
const mainService = Container.get(MainService);
console.log(mainService.getValue()); // Output: Dependency Value
```
Container
The `Container` class is used to manage the lifecycle of services. You can manually set and get instances of services using `Container.set` and `Container.get`.
```typescript
import { Container } from 'typedi';
class ExampleService {
sayHello() {
return 'Hello, World!';
}
}
Container.set(ExampleService, new ExampleService());
const exampleService = Container.get(ExampleService);
console.log(exampleService.sayHello()); // Output: Hello, World!
```
Other packages similar to typedi
inversify
Inversify is a powerful and flexible inversion of control (IoC) container for JavaScript and TypeScript. It provides a similar feature set to TypeDI, including decorators for services and dependency injection. Inversify is known for its extensive documentation and strong community support.
tsyringe
TSyringe is a lightweight dependency injection container for TypeScript. It offers a similar decorator-based API for defining and injecting services. TSyringe is designed to be simple and easy to use, making it a good choice for smaller projects or those new to dependency injection.
awilix
Awilix is a dependency injection container for JavaScript and TypeScript that focuses on developer experience and ease of use. It provides a fluent API for defining and resolving dependencies, and supports both class-based and function-based services. Awilix is known for its flexibility and ease of integration with various frameworks.
TypeDI
Dependency injection tool for Typescript.
Usage
If you simply want to use a container:
import {Container} from "typedi/Container";
class SomeClass {
someMethod() {
}
}
let someClass = Container.get<SomeClass>(SomeClass);
someClass.someMethod();
If you want to inject other classes into your service you can do:
import {Container} from "typedi/Container";
import {Inject} from "typedi/Decorators";
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);
coffeeMaker.make();
If you want to use constructor injection:
import {Container} from "typedi/Container";
import {Service} from "typedi/Decorators";
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);
coffeeMaker.make();
Also you can inject a modules that you want to require
:
import {Container} from "typedi/Container";
import {Service, Require} from "typedi/Decorators";
@Service()
class CoffeeMaker {
private gulp: any;
constructor(@Require('gulp') gulp: any) {
this.gulp = gulp;
}
make() {
console.log(this.gulp);
}
}
let coffeeMaker = Container.get<CoffeeMaker>(CoffeeMaker);
coffeeMaker.make();
Named services
You can use a named services. In this case you can use interface-based services.
import {Container} from "typedi/Container";
import {Service, Inject} from "typedi/Decorators";
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());
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() }
]);
Take a look on samples in ./sample
for more examples of usages.