DEV Community

Cover image for Custom injecting logic for NestJS with support multi providing
ILshat Khamitov
ILshat Khamitov

Posted on

Custom injecting logic for NestJS with support multi providing

Installation

npm i --save nestjs-custom-injector
Enter fullscreen mode Exit fullscreen mode

Links

https://nestjs-custom-injector.site15.ru/api - Demo application with nestjs-custom-injector.
https://github.com/EndyKaufman/nestjs-custom-injector-example - Example generated with nest cli for "Usage" sections in readme.

Usage

Create common interface with token in animal-provider.interface.ts

export const ANIMAL_PROVIDER = 'ANIMAL_PROVIDER';

export interface AnimalProviderInteface {
  type: string;
  say(): string;
}
Enter fullscreen mode Exit fullscreen mode

Create first type of logic for cats in animal-cats.service.ts

import { Injectable } from '@nestjs/common';
import { AnimalProviderInteface } from './animal-provider.interface';

@Injectable()
export class AnimalCatsService implements AnimalProviderInteface {
  type = 'cat';
  say(): string {
    return 'meow';
  }
}
Enter fullscreen mode Exit fullscreen mode

Create second type of logic for dogs in animal-dogs.service.ts

import { Injectable } from '@nestjs/common';
import { AnimalProviderInteface } from './animal-provider.interface';

@Injectable()
export class AnimalDogsService implements AnimalProviderInteface {
  type = 'dog';
  say(): string {
    return 'woof';
  }
}
Enter fullscreen mode Exit fullscreen mode

Create controller animals.controller.ts

import { Controller, Get, Query } from '@nestjs/common';
import { CustomInject } from 'nestjs-custom-injector';
import {
  AnimalProviderInteface,
  ANIMAL_PROVIDER,
} from './animal-provider.interface';

@Controller('animals')
export class AnimalsController {
  @CustomInject(ANIMAL_PROVIDER, { multi: true })
  private animalProviders!: AnimalProviderInteface[];

  @Get('animal-types')
  animalTypes() {
    return this.animalProviders.map((animalProvider) => animalProvider.type);
  }

  @Get('what-says-animals')
  whatSaysAnimals() {
    return this.animalProviders.map(
      (animal) => `${animal.type} say ${animal.say()}`
    );
  }

  @Get('who-say')
  whoSay(@Query('voice') voice: string) {
    const animal = this.animalProviders.find(
      (animal) => animal.say() === voice
    );
    if (!animal) {
      return { error: `I don't know who say ${voice}` };
    }
    return `${animal.type} say ${animal.say()}`;
  }
}
Enter fullscreen mode Exit fullscreen mode

Append all logic to main app module app.module.ts

import { Module } from '@nestjs/common';
import { CustomInjectorModule } from 'nestjs-custom-injector';
import { AnimalCatsService } from './animal-cats.service';
import { AnimalDogsService } from './animal-dogs.service';
import { AnimalsController } from './animals.controller';

@Module({
  ...
  imports: [
    ...
    CustomInjectorModule.forRoot(),
    CustomInjectorModule.forFeature({
      providers: [{ provide: ANIMAL_PROVIDER, useClass: AnimalCatsService }],
    }),
    CustomInjectorModule.forFeature({
      providers: [
        { provide: ANIMAL_PROVIDER, useValue: new AnimalDogsService() },
      ],
    }),
    ...
  ],
  controllers: [
    ...
    AnimalsController
    ...
  ]
  ...
})
export class AppModule {}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)