DI-Container

Learn more about our DI-Container

Introduction

Dependency Injection is the way to go, if you want to create clean and structured code. It helps you to resolve required dependencies for your classes. Keep in mind, dependency injection only works inside the constructor.

We're using tsyringe from Microsoft as our di-container solution. It fits all our needs and is really lightweight.

If you want more informations about tsyringe, please read the documentation on GitHub.

We will not go into how Dependency Injection works, but only how we use it.

tsyringe Decorators

@singleton

If you want to have the same instance of the class every time, use the @singleton decorator.

@singleton()
export class MyClass {}

// resolve class from container
const resolve1 = container.resolve(MyClass);
const resolve2 = container.resolve(MyClass);

resolve1 === resolve2;

@injectable

If you want to have a new instance of the class every time, use the @injectable decorator.

@injectable()
export class MyClass {}

// resolve class from container
const resolve1 = container.resolve(MyClass);
const resolve2 = container.resolve(MyClass);

resolve1 !== resolve2;

Custom DI Decorators

We created some custom decorators to interact with the di-container. They are needed for internal work. The entire framework uses many shared classes and helpers on both sides. The decorators help us to connect the server and client with the shared classes.

Every custom decorator must be declared after the tsyringe decorator

@Module

The @Module decorator is the most used custom decorator. This decorator handles all your other module imports and components. It combines the autoloading feature and @StringResolver

container.resolve(FirstModule)

The example above shows you the magic. Only one line of code for import. Resolve the module from container, autoload all other declared modules and components. This keep your code clean and good-looking.

@Component

This @Component decorator is a simple decorator for readable code. It is the same as @singleton but fits the framework read language better

@Component()
export class YourComponent{}

@StringResolver

The @StringResolver registers the decorated class as a string InjectionToken inside the DI-container. This is needed if you want to resolve a class based on the string constructor name

This decorator is only needed, if you get errors on resolving your class. There are not many usecases.

@StringResolver
export class MyClass {}

// resolve class from container
const resolve1 = container.resolve('MyClass');

resolve1 instanceof MyClass === true

Last updated