【问题标题】:Does dependency injection (in NestJS, for example) depends on TypeScript features?依赖注入(例如在 NestJS 中)是否依赖于 TypeScript 功能?
【发布时间】:2021-04-24 16:36:59
【问题描述】:

在 NestJS 中应用依赖注入模式时,例如在 this example from the documentation 中:

import { Controller, Get, Post, Body } from '@nestjs/common';
import { CreateCatDto } from './dto/create-cat.dto';
import { CatsService } from './cats.service';
import { Cat } from './interfaces/cat.interface';

@Controller('cats')
export class CatsController {
  constructor(private catsService: CatsService) {}

  // Some other methods...
}

这是如何工作的?据我了解,TypeScript 会被编译成纯 JavaScript,然后类类型(CatsService)就会消失。在这种情况下,NestJS 是如何知道要注入什么类的?

【问题讨论】:

标签: typescript dependency-injection nestjs


【解决方案1】:

看看这个例子。这个:

@Injectable()
export default class RequestService {
  constructor(
    @InjectRepository(RequestEntity)
    private requestEntityRepository: Repository<RequestEntity>,
  ) {}

正在被转译成这个:

let RequestService = class RequestService {
    constructor(requestEntityRepository) {
        this.requestEntityRepository = requestEntityRepository;
    }
...

RequestService = __decorate([
    common_1.Injectable(),
    __param(0, typeorm_1.InjectRepository(RequestEntity_1.default)),
    __metadata("design:paramtypes", [typeorm_2.Repository])
], RequestService);
exports.default = RequestService;

【讨论】:

    【解决方案2】:

    依赖注入一般不依赖于 typescript,甚至在 NestJS 中也可以通过使用 Babel 作为转译器在(大部分)纯 JavaScript 中完成。 I've gone into a bit of detail here 关于装饰器如何使用打字稿,Semyon Volkov 也展示了装饰器如何转换。所以本质上,不,它不依赖于 Typescript,Nest 希望你这样做(固执己见)的方式。

    在您的示例中,Nest 将读取 design:paramtypes 的类型并看到有一个 CatsService 类,因此它知道匹配类名并在此处注入 CatsService。在跟踪哪些模块可以访问哪些内容时,幕后还有很多事情要做,但这是大体思路。

    【讨论】:

      【解决方案3】:

      依赖注入不依赖于打字稿。每当我们启动 Nest 应用程序时,都会为我们创建一个依赖注入 (DI) 容器。 DI 只是一个对象。

      Nest 将查看我们创建的所有不同类,但控制器除外。它将向 DI 容器注册所有这些不同的类。容器将检查每个类所需的所有依赖项,并将该类映射到其依赖项:

         class1 ---> dependencies
         class2 ---> dependencies
         class3 ---> it might now have any dependency
      

      然后最终我们要创建控制器。我们告诉 DI 创建具有所需依赖项的控制器。 DI 将查看构造函数参数并查看所需的所有依赖项。容器会看到它需要创建一个服务并且服务需要创建一些依赖项。

      因此 DI 容器将创建所需依赖项的实例并在内部存储每个实例,因此如果将来另一个类需要这些实例,它可以使用它们。现在已经创建了依赖项,DI 容器将使用它们来创建 Controller 并返回它。

      如您所见,我们不必担心自己创建所有这些服务。 DI 容器会为我们处理好它。

      依赖注入用于重用代码并更轻松地测试应用程序。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-12-24
        • 2021-12-01
        • 2021-04-06
        • 2013-04-10
        • 2021-11-19
        • 2020-03-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多