ezinjector
v3.3.2
Published
IoC container for ES and TypeScript (Compatible with ts-ioc-compiler)
Downloads
22
Readme
ezinjector
Small lightweight (~3kb minified) module for Inversion of Control (IoC Container) and Dependency Injection for JavaScript, EcmaScript and TypeScript.
$ npm install ezinjector --save
Use ts-ezinjector-compiler if using typescript for syntactic sugar, and interface intellisense: https://github.com/jeppeskovsen/ts-ezinjector-compiler
(examples will use that)
$ npm install ts-ezinjector-compiler --save-dev
Usage
It is not necessary to wrap the container inside a class, but this will make sure container.register
happens sooner.
import { Container, Instantiate, Setup } from "ezinjector";
import { CustomService } from "./custom.service";
@Setup()
class EzInjector {
constructor() {
const container = new Container();
container.register<ICustomService>(CustomService);
container.register<IAnotherCustomService>(IAnotherCustomService, Instantiate.EachRequest);
container.verify();
}
}
Instantiate is an enum with 3 properties:
enum Instantiate {
WhenInjected, // default
RightAway,
ForEachRequest
}
Getting the instance of the class without dependency injection:
import { Container } from "ezinjector";
const customService = Container.getInstance<ICustomService>(CustomService);
Dependency Injection
There are two ways to inject into a class, that is registered in the container.
Via contructor
import { Inject } from "ezinjector";
export class CustomService implements ICustomService {
constructor(
@Inject<IAnotherCustomService>() private customService2: IAnotherCustomService
) {}
public customMethod(): string {
return this.customService2.someMethod();
}
}
Via properties
import { Inject, StaticInject } from "ezinjector";
export class CustomService implements ICustomService {
@StaticInject<IAnotherCustomService>()
customService2: IAnotherCustomService;
@Inject<IYetAnotherCustomService>()
customService3: IYetAnotherCustomService;
public customMethod(): string {
return this.customService2.someMethod();
}
}
@Resolve()
@Resolve
is a class decorator used to inject into a class where you don't control the instantiation of the class.
import { Injectable } from "ezinjector";
@Resolve()
export class SomeModule {
constructor(
@Inject<ICustomService>() private customService: ICustomService = null
) {}
}
This class will inject whenever the class is newed up.
I've sat the default value to null in this case, because @Resolve
will overwrite constructor arguments, so we can just call the class like this:
new SomeModule();
But could also be:
new SomeModule(null);
Resolve also takes interfaces (up to 10 in the definition file), so we can use it like this:
import { Injectable } from "ezinjector";
@Resolve<ICustomService, IAnotherCustomService>()
export class SomeModule {
constructor(
private customService: ICustomService,
private anotherCustomService: IAnotherCustomService
) {}
}
Or with smart inject in ts-ezinjector-compiler, it will find out automatically:
import { Resolve } from "ezinjector";
@Resolve()
export class SomeModule {
// @ezInject
constructor(
private customService: ICustomService,
private anotherCustomService: IAnotherCustomService
) {}
}
@Inject() vs @StaticInject()
@StaticInject
will try to inject the property immediately, where @Inject
will inject when instance is created.
@StaticInject
only works for properties, and not constructor arguments.
@StaticInject
can for example be used in classes where you do not instatiate them yourself - like a React Component.
Without ts-ezinjector-compiler (magic strings)
Without the ts-ezinjector-compiler (or with JS/ES) we use magic strings to define our references:
@Inject("ICustomService");
@StaticInject("ICustomService");
@Resolve("ICumstomService", "IAnotherCumstomService");
container.register("ICustomService", CustomService);
Container.getInstance("ICustomService", CustomService);