Nest.js:动态模块中的循环依赖

dol*_*s3m 7 nestjs

当动态模块之间存在循环依赖时,导入动态模块的正确方法是什么?我只是更改forwardRef(() => MyModule)forwardRef(() => MyModule.forRoot()),但Nest can't resolve dependencies出现错误。

Ane*_*eed 18

处理嵌套模块依赖的最佳方法是始终通过模块而不是通过服务导入依赖项。如果您遇到循环依赖,nest 会显示一个错误,您可以使用 forwardRef() 轻松修复它。

假设您的应用程序有 3 个紧密耦合的模块。

  • @moduleA()
  • @moduleB()
  • @moduleC()

以及两个配套模块

  • @moduleX()
  • @moduleY()
  • @moduleZ()

此外,所有模块都以相同的名称导出服务。

考虑这样一种情况

@moduleA() 导入 [serviceB, serviceX]

@moduleB() 导入 [serviceA, serviceY, serviceZ]

现在,@moduleC()如果你想使用 serivceA() 那么你将不得不

@moduleC() 导入 [serviceA, serviceB, serviceX, serviceY, serviceZ]

在大多数情况下,nest 会抛出正确的错误,说明缺少哪个依赖项。但有时,nest 只说 [ index] 处的依赖项丢失,nest 没有说它在哪里丢失。这将导致很大程度的混乱。

一种巧妙的方法是始终导入模块

@moduleA() 导入 [moduleB, moduleX]

@moduleB() 导入 [moduleA, moduleY, moduleZ]

@moduleC() 导入 [moduleA]


如果 nest 再次抱怨依赖问题,则使用导入模块 forwardRef

@module({
     imports: [
       forwardRef(() => ModuleA)
       ModuleB
       ],
    controllers: [],
    providers: []
})
Run Code Online (Sandbox Code Playgroud)

有时即使在完成所有这些之后,您可能会再次遇到依赖项不可用错误。然后你可以使用ModuleRef. 让我们举同样的例子,你想在 ModuleC() 中使用 ServiceA()

然后,您将在 ModuleC() 和 serviceC() 类中将 serviceA() 添加到 providers[] 中,您需要添加以下内容。

import { Injectable, OnModuleInit } from '@nestjs/common'; \\need OnModuleInit 
import { ServiceA} from '../FolderA/serviceA.service';

export class ServiceC implements OnModuleInit {
   
   private serviceA: ServiceA;
   constructor(private readonly moduleRef: ModuleRef) {}

   onModuleInit() {
        this.serviceA= this.moduleRef.get(ServiceA);
    }
   
   foo(){
     console.log(this.serviceA.someFunction())
   }
}
Run Code Online (Sandbox Code Playgroud)

请在官方文档中查看更多信息

  • 如果有人确定他们没有循环依赖项,但仍然收到此错误消息,请密切注意“*.module.ts”中的“imports”属性。我发现有两个逗号,如“,,”会导致此错误。 (2认同)