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

时间:2019-06-03 18:37:07

标签: nestjs

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

1 个答案:

答案 0 :(得分:2)

处理嵌套模块依赖关系的最佳方法是始终通过模块而不是通过服务导入依赖关系。如果遇到循环依赖关系,则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会抛出正确的错误,指出缺少哪个依赖项。但是有时候,巢只说[index]的依赖项丢失了,巢没有说缺少的依赖项。这将导致高度混乱。

一种整洁的方法是始终导入模块

  

@moduleA()导入[moduleB,moduleX]

     

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

     

@moduleC()导入[moduleA]


如果nest再次抱怨依赖关系问题,请使用forwardRef

导入模块
@module({
     imports: [
       forwardRef(() => ModuleA)
       ModuleB
       ],
    controllers: [],
    providers: []
})

有时即使完成所有这些操作,您仍然可能再次遇到依赖项不可用错误。然后,您可以使用ModuleRef。让我们以相同的示例为例,您要在ModuleC()中使用ServiceA()

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

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())
   }
}

请在Official documentation中查看更多信息。