【问题标题】:How nestjs works and runs constructors with parameternestjs 如何工作并使用参数运行构造函数
【发布时间】:2020-05-09 01:31:07
【问题描述】:

我是nestJS 的新手,也找不到太多关于它的信息,所以我也不敢深入研究它的源代码(也是打字稿的初学者)。我真的很想知道我将在下面提到的那些东西是如何工作的

首先: 我正在观看我们有名为 Task 的服务的教程

export class TasksController {
  constructor(private readonly tasksService: TasksService) { }

  Get()
  index() {
     this.tasksService.all();
  }
}

这里TasksService 仅用作一种类型,而不是我猜的类。在普通的打字稿中,我会写类似的东西

let task = new TasksController(new TasksService())

那我就可以打电话给this.tasksService.all();

第二: @Injectable()@Inject()@InjectRepository() 等如何工作。原始文档有点混乱:(

【问题讨论】:

    标签: typescript nestjs typeorm


    【解决方案1】:

    它建立在Angular 的思想之上,它与Dependency InjectionSeparation of Concerns 打交道。这些想法来自更多面向对象的语言,如 Java 和 C++,尤其是来自 Spring/SpringBoot 等框架。

    简介

    除此之外,Nest 通过将提供程序“连接”在一起做了很多事情,让开发人员不必担心实例化每个类,而是让框架为他们处理。我先谈谈你的第二点,希望它有助于阐明第一点。

    Injectable Inject 和 InjectRepository 装饰器

    打字稿中的所有装饰器都用于设置元数据。 Nest 将读取此元数据并做出相应的响应。在大多数情况下,这一切都是通过 DI 系统的设置在幕后处理的。

    • @Injectable() 告诉 Nest “嘿,这个类是一个提供者*,因此它应该能够将值注入其中并能够注入其他提供者。你所有的服务都将被标记为 @987654327 @ 以及一些特殊的类。

    • @Inject() 是一个接受注入令牌**的装饰器。这告诉 Nest “嘿,我想注入与我刚刚给你的令牌相关联的提供程序。创建一个实例并在此处注入它。令牌可以是字符串或符号,但它必须是唯一的(即不与另一个冲突) provider)。使用时可以多次使用同一个令牌。

    • @InjectRepository()/@InjectModel() 这些是特殊的 @Inject() 装饰器,它们在底层使用标准的 @Inject() 装饰器来保持注入令牌与 Nest 已经在 TypeormModule 和 @ 中创建的注入令牌一致987654334@

    它是如何工作的(有点)

    现在我们对装饰器设置的元数据有了更多的了解,让我们来谈谈 Nest 如何解决依赖关系。嵌套的作用是扫描每个类并查找元数据是否为@Injectable()。 (@Controller() 和其他装饰器确实设置了这个)。然后它查看构造函数中的类并确定该类是否具有注入令牌(除非另有说明,否则类仅由名称确定***)。如果没有,它会检查是否有一个 @Inject() 装饰器并找到它要使用的特定值。如果它找到一个类,它将实例化它,将其保存在缓存中,并将其提供给该类。如果是值,则直接提供给类。

    为了更深入地了解,请阅读 DI 以及其他框架如何处理它。 Angular 是一个很好的资源,因为正如我所说,Nest 从中获得了很多灵感

    脚注:

    *例外情况包括警卫、拦截器、管道和过滤器。虽然这些是@Injectable(),但它们不是普通的提供者。

    ** 这是真的,除非您正在处理类成员注入,在这种情况下您不提供令牌。

    ***您可以使用自定义提供程序进行管理

    【讨论】:

    • 哇真的很详细。但这是我第一次听说你上面提到的那些令牌。你知道有什么来源可以获取更多信息吗?另一个想法如果我误解了,请告诉我,我理解这样的想法:“Nest 还将在我们在 providers 数组中定义的模块内使用该数据(类)。当运行这些构造函数方法时,它将使用我们定义的那些类在模块类上”。
    • 我说的对吗?可能不会,因为我还在构造方法等上使用了其他可注入类(除了服务之外)。例如 dto。在控制器中将其称为create(@Body() createTaskDto: CreateTaskDto),其中 CreateTaskDto 表示类型,我猜是接口。但是然后巢是如何确定它的。太长了抱歉:(
    • 我认为你的说法是正确的。到目前为止,我们讨论的所有内容都是基于构造函数的注入器。 Nest 确实有一些基于方法的注入器(例如 @Body()),它们只在路由上工作。那是另一个故事。要了解有关 Nest 使用 DI 令牌的更多信息you can read up on custom providers。最后,Nest 需要类或 DI 令牌来知道要注入什么,因为接口在运行时不存在,它们不能用于注入令牌。
    • 很好很好的解释杰伊!写得好!
    猜你喜欢
    • 1970-01-01
    • 2020-07-10
    • 2019-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-23
    • 1970-01-01
    相关资源
    最近更新 更多