Dependency Injection

The Dependency Injection system is one of the most fundamental building blocks of Zibri.

To make something injectable there are 2 ways:

  1. decorate a class with @Injectable()
  2. add the value to your providers array

In most cases, you will probably just have to decorate a class:

// src/services/test.service.ts
import { Injectable } from 'zibri';

@Injectable()
export class TestService {
// ...
}

Now you can easily inject the TestService either by adding it to a constructor or by using the inject helper:

// src/controllers/test.controller.ts
import { Controller, inject } from 'zibri';

import { TestService } from '../services';

@Controller('/tests')
export class TestController {
constructor(private readonly testService: TestService) {
const alternative: TestService = inject(TestService);
}
// ...
}

Alternatively, you can also add them to the providers array:

// src/providers.ts
import { DiProvider, ZIBRI_DI_TOKENS } from 'zibri';

export const providers: DiProvider<unknown>[] = [
// ...
{
token: 'some-token',
useFactory: () => '42'
}
// ...
]

And then inject them the same way before, with the constructor approach needing an additional decorator:

// src/controllers/test.controller.ts
import { Controller, inject } from 'zibri';

@Controller('/tests')
export class TestController {
constructor(
@Inject('some-token')
private readonly value: string
) {
const alternative: string = inject('some-token');
}
// ...
}

Bascially every service/functionality of the framework is registered for dependency injection. That makes it really easy for you to replace something with your own implementation if you need more functionality than the builtin solutions.

Let's say that you want for example to replace the default error handler with the following one:

// src/my-error-handler.ts
import { NextFunction } from 'express';
import { GlobalErrorHandler, HttpRequest, HttpResponse } from 'zibri';

export const myErrorHandler: GlobalErrorHandler = async (error: unknown, req: HttpRequest, res: HttpResponse, next: NextFunction) => {
// ...your custom logic
}

For that you can simply add it to your providers array:

// src/providers.ts
import { DiProvider, ZIBRI_DI_TOKENS } from 'zibri';

import { myErrorHandler } from './my-error-handler.ts';

export const providers: DiProvider<unknown>[] = [
// ...
{
token: ZIBRI_DI_TOKENS.GLOBAL_ERROR_HANDLER,
useFactory: () => myErrorHandler
}
// ...
]

That's it! From now on, your custom error handler will be used instead of the default one provided by Zibri.