#nestjs
#nestjs
Вопрос:
У меня есть приложение, которое получает сервис в качестве зависимости от контроллера, пока все хорошо, но я хотел бы найти способ вместо объявления конкретной реализации этого сервиса, чтобы иметь возможность «запрашивать» у контроллера интерфейс, который реализует этот сервис, для отделения от контроллера.конкретная реализация этого сервиса. Как это делается в nest js?
Ответ №1:
Для этого вам нужно создать токен для вашего интерфейса и использовать @Inject()
декоратор с токеном для инъекций при внедрении вашего сервиса. Затем в вашем модуле вы можете объявить, какую реализацию предоставить для этого токена внедрения.
Ниже приведен простой интерфейс службы приветствия и наш токен внедрения, который будет использоваться при регистрации нашей службы в качестве поставщика.
приветствие-service.interface.ts
// This will be our injection token.
export const GREETING_SERVICE = 'GREETING SERVICE';
export interface IGreetingService {
greet(name: string): Promise<string>;
}
Базовая служба, которая будет реализовывать наш интерфейс приветствия…
professional-greeting.service.ts
import { Injectable } from '@nestjs/common';
import { IGreetingService } from './greeting-service.interface';
@Injectable()
export class ProfessionalGreetingService implements IGreetingService {
public async greet(name: string): Promise<string> {
return `Hello ${name}, how are you today?`;
}
}
И наш модуль приветствия, где мы регистрируем наш сервис с помощью токена…
приветствие.module.ts
import { Module } from '@nestjs/common';
import { ProfessionalGreetingService } from './services/professional-greeting.service';
import { GREETING_SERVICE } from './services/greeting-service.interface';
import { GreetingController } from './controllers/greeting.controller';
@Module({
providers: [
{
// You can switch useClass to different implementation
useClass: ProfessionalGreetingService,
provide: GREETING_SERVICE
}
],
controllers: [
GreetingController
]
})
export class GreetingModule {}
Теперь, когда мы внедряем наш сервис, мы можем использовать @Inject()
декоратор с нашим токеном внедрения. Какая бы реализация, которую вы продемонстрировали useClass
в our GreetingModule
, будет внедрена…
приветствие.controller.ts
import { Controller, Get, Inject, Query } from '@nestjs/common';
import { GREETING_SERVICE, IGreetingService } from '../services/greeting-service.interface';
@Controller('greeting')
export class GreetingController {
constructor(
@Inject(GREETING_SERVICE)
private readonly _greetingService: IGreetingService
) {}
@Get()
public async getGreeting(@Query('name') name: string): Promise<string> {
return await this._greetingService.greet(name || 'John');
}
}
https://github.com/jmw5598/nestjs-di-decoupling-with-interfaces
https://docs.nestjs.com/fundamentals/custom-providers