首页 > 解决方案 > NestJS 中的 DI 是如何工作的?

问题描述

有以下标准NestJS代码:

import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get()
  getHello(): string {
    return this.appService.getHello();
  }
}

还有模块应用程序的代码:

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  imports: [],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

我不明白应用程序如何理解应用程序控制器期望将应用程序服务作为第一个参数?起初我认为应用程序只是查看提供程序数组并将该数组中的所有服务放入控制器的构造函数中。但我可以通过这种方式更改代码:

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  imports: [],
  controllers: [AppController],
  providers: [AppService, NewService],
})
export class AppModule {}

现在我不仅可以在AppController类中使用这个NewService ,还可以在AppService类中使用它。app 怎么知道现在我可以在AppService 类中使用NewService了?现在我不明白我们该怎么做,因为TypeScript只是语法糖并且只存在直到编译完成并且我知道应用程序无法查看AppService中的参数类型(例如fileService: FileService)并放入将创建AppService时将正确的服务作为参数。我需要这个机制下的技术细节,而不仅仅是官方教程中的用例。

标签: javascriptnestjs

解决方案


通过在 providers 数组中注册它,您可以将它注册到 Nest IoC 容器。

如果你检查编译的 js 代码,那么你会发现类似

WeatherHttpProvider = __decorate([
    (0, common_1.Injectable)(),
    __param(1, (0, common_1.Inject)(weather_parser_1.WEATHER_PARSER)),
    __metadata("design:paramtypes", [axios_1.HttpService, Object])
], WeatherHttpProvider);

在这种情况下,它告诉 WeatherHttpProvider 注入的构造函数参数。这样它就知道要使用 IoC 容器中的哪个类。


推荐阅读