Dependency Injection container (IoC) for TypeScript.
- Type based dependency injetion
- Type auto registration
- Lifecycle methods
- Interface based injection
- Name based injection (hints)
- Property value injection
- Constructor injection (parameters)
- Singletons vs Instances
- Factories
- External components (components where the constructor could not be called by tsdi)
- Lazy dependency injection (default)
- Lifecycle listeners
- Eager components
- Debug logging
- Automocks
Install as npm package:
npm install tsdi --save
Install latest development version:
npm install tsdi@next --save
import { Component } from 'tsdi';
@Component()
export class Dependency {
public echo(input: string): string {
return input;
}
}
import { Component, Inject, Initialize } from 'tsdi';
import { Dependency } from './dependency';
@Component()
export class User {
@Inject()
private dependency: Dependency;
private message: string;
@Initialize()
public init(): void {
this.message = 'hello';
}
public getDep(): Dependency {
return this.dependency;
}
public method(): string {
return this.dependency.echo(this.message);
}
}
import { TSDI } from 'tsdi';
import { User } from './user';
import { Dependency } from './dependency';
const tsdi: TSDI = new TSDI();
tsdi.register(User);
tsdi.register(Dependency);
const user: User = tsdi.get(User);
console.log(user.method()); // outputs 'hello'
import { TSDI, Component, Inject } from 'tsdi';
@Component()
class A {}
@Component()
class B extends A {}
@Component({name: 'Bar'})
class C extends A {}
@Component({name: 'Foo'})
class D extends A {
@Inject({name: 'Bar'})
private a: A;
}
const tsdi: TSDI = new TSDI();
tsdi.enableComponentScanner();
const a: A = tsdi.get(A, 'Foo');
import { TSDI, Component, Inject } from 'tsdi';
@Component()
class A {}
@Component()
class B {}
@Component()
class C {
constructor(@Inject() a: A, @Inject() b: B) {}
}
const tsdi: TSDI = new TSDI();
tsdi.enableComponentScanner();
tsdi.get(C);
import { TSDI, Component } from 'tsdi';
@Component({singleton: false})
class A {}
@Component()
class B {}
const tsdi: TSDI = new TSDI();
tsdi.enableComponentScanner();
const a0: A = tsdi.get(A);
const a1: A = tsdi.get(A);
// a0 !== a1
const b0: B = tsdi.get(B);
const b1: B = tsdi.get(B);
// b0 === b1
import { TSDI, Component, Factory } from 'tsdi';
class A {}
@Component()
class B {
@Factory()
public createA(): A {
return new A();
}
}
const tsdi: TSDI = new TSDI();
tsdi.enableComponentScanner();
tsdi.get(A);
import { TSDI, Component, Inject } from 'tsdi';
@Component()
class A {
@Inject({name: 'config-key'})
public some: string;
}
const tsdi: TSDI = new TSDI();
tsdi.addProperty('config-key', 'config-value');
tsdi.register(A);
console.log(tsdi.get(A).some); // 'config-value'
import { TSDI, Component, External } from 'tsdi';
@Component
class A {}
@Component
class B {}
@External()
class C {
@Inject()
public a: A;
public b: B;
constructor(@Inject() b: B) {
this.b = b;
}
@Initialize()
public init() {
}
}
const tsdi: TSDI = new TSDI();
tsdi.enableComponentScanner();
const c = new C();
console.log(c.a);
import { TSDI, Component, Inject } from 'tsdi';
@Component()
class A {
@Inject({lazy: true})
public some: Dependency;
}
const tsdi: TSDI = new TSDI();
tsdi.register(A);
const a = tsdi.get(A); // <-- at this point a.some is still undefined (not created and not injected)
console.log(a.some); // <-- at this point some is created and return (on first property access)
import { TSDI, Component, Inject } from 'tsdi';
@component
class A {
}
const tsdi: TSDI = new TSDI();
tsdi.register(A);
tsdi.addLifecycleListener({
onCreate(component: any): void {
console.log(component); // <-- this line is executed the first time a component is created
}
});
const a = tsdi.get(A);
import { TSDI, Component, Inject } from 'tsdi';
@component({eager: true})
class A {
}
const tsdi: TSDI = new TSDI();
tsdi.register(A); // <-- here the class A is instantiated
To inspect which component is created when and injected where one can enable debug logging by either
set the environment variable DEBUG
(node) or a localStorage key (browser) debug
to tsdi
.
import { TSDI, component, inject, initialize } from 'tsdi';
@component
class Foo {
public foo(): void {
}
}
@component
class Bar {
public bar(): string {
return 'bar';
}
}
@component
class Baz {
@inject
public foo: Foo;
@inject
public bar: Bar;
@initialize
protected init(): void {
this.foo.foo();
console.log(this.bar.bar()); // <-- logs 'bar' since this.bar is not mocked
}
}
// This means: create mocks for all inject but 'Bar'
tsdi.enableAutomock(Bar);
tsdi.get(Baz);
- Static factories
- Factories for non classes/types