InjectRepository 在 NestJS 内部如何工作? [英] How does InjectRepository work internally in NestJS?

查看:152
本文介绍了InjectRepository 在 NestJS 内部如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 nestjs 中,我明白

In nestjs, I understand that

imports: [
    TypeOrmModule.forFeature([TaskRepository]),
],

创建某种提供者令牌,然后我可以使用此令牌将存储库注入我的服务(在同一模块中).

creates some kind of provider token so then I can inject the repository in my service (in same module) with this token.

我不明白的是 @InjectRepository() 在内部是如何工作的,例如:

What I don't understand is how @InjectRepository() works internally, for example:

constructor(
    @InjectRepository(TaskRepository)
    private taskRepository: TaskRepository,
  ) {}

InjectRepository 自定义装饰器(应该使用 createParamDecorator 创建)如何能够注入在模块中注册的提供程序?我研究并发现 createParamDecorator 不能使用 DI.如果 createParamDecorator 只是创建一个新的 TaskRepository 实例并返回它,那么为什么我需要在模块中导入 TypeOrmModule.forFeature ?有人可以解释一下这在内部是如何工作的吗?谢谢!

How is InjectRepository custom decorator (which should have been created with createParamDecorator) able to inject a provider registered in a module? I researched and found out that createParamDecorator doesn't have ability to use DI. If createParamDecorator just creates a new TaskRepository instance and returns it, then why do I need to import TypeOrmModule.forFeature in module? Can someone explain how this works internally? Thanks!

推荐答案

你走在正确的轨道上,但 @InjectRespoitory()createParamDecorator() 通常是两种不同的装饰器类型.是的,它们都适用于参数,但它们通常具有不同的用例.

You're on the right track, but @InjectRespoitory() and createParamDecorator() are generally two different decorator types. Yes they both work on parameters, but they generally have different use cases.

createParamDecorator 作用于控制器、解析器和网关路由处理程序,因此 Nest 可以知道 reqcontextpayload 对象(或您想要获取的 ExecutionContext 的任何其他部分)应该放入路由处理程序的参数位置.其背后的代码有点复杂,但如果你真的很好奇,我可以指出它.

createParamDecorator works on controller, resolver, and gateway route handlers, so that Nest can know what part of the req, context, or payload object (or whatever other part of the ExecutionContext you want to get) should be put into the route handler's parameter position. The code behind that is a little complex, but I can point you to it if you get really curious.

@InjectRepository() 另一方面是 @Inject() 的扩展,它采用当前传递的实体/存储库并使用一些逻辑来创建新的注入令牌.通常,此逻辑是 Repository 有时会添加 connection.此令牌与从 TypeormModule.forFeature() 为同一实体创建的令牌匹配.(旁注:如果传递的实体是存储库,则令牌只是 带有可选连接(如果不是默认连接).

@InjectRepository() on the other hand is an extension of @Inject() that takes the currently passed entity/repository and uses some logic to create a new injection token. Generally, this logic is <EntityName>Repository sometimes with a connection added to it. This token matches up with the created token from TypeormModule.forFeature() for the same entity. (Side note: if the entity passed is a repository, the token is just <EntityName> with the optional connection if it is not the default one).

你可以试试这个,但是去掉 @InjectRepository() 而是使用 @Inject() 只是为了测试目的,但我不建议在生产服务器实例.出错的机会太多了.

You can try this out but getting rid of @InjectRepository() and instead using @Inject() just for testing purposes, but I wouldn't suggest that in a production server instance. Too many chances it will go wrong.

这里要注意的真正重要的事情是 @InjectRepository() 实际上并没有注入任何东西.它只是为 Nest 设置元数据以读取并匹配自定义提供程序.TypeormModule.forFeature() 实际上是这里的繁重工作,使用匹配的注入令牌创建自定义提供程序并为提供程序提供正确的值.

The really important thing to make note of here is that @InjectRepository() doesn't actually inject anything. It just sets up the metadata for Nest to read and match to a custom provider. TypeormModule.forFeature() is actually what's doing the heavy lifting here, creating a custom provider with a matching injection token and providing the right value for the provider.

顺便说一下,@InjectRepository()TypeormModule.forFeature() 必须一起工作,因为 Typescript 不能正确反映泛型.通常,对于 Nest,我们可以使用类名作为注入令牌,但是诸如 Repository 之类的东西只是作为 Repository 返回,因此 Nest 不知道 哪个em> 要注入的存储库.通过使用 @InjectRepository() 装饰器,我们能够设置注入令牌元数据并覆盖反射的类值.

By the way, @InjectRepository() and TypeormModule.forFeature() have to work together because Typescript cannot reflect generics properly. Normally with Nest we can use class names as injection tokens, but something like Repository<TaskEntity> just comes back as Repository so Nest wouldn't know which repository to inject. By using the @InjectRepository() decorator we are able to set the injection token metadata and override the reflected class value.

这篇关于InjectRepository 在 NestJS 内部如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆