循环依赖
循环依赖发生在两个类相互依赖时。例如,类 A 需要类 B,而类 B 也需要类 A。在 Nest 中,循环依赖可能出现在模块之间和提供者之间。
虽然应尽可能避免循环依赖,但并非总能做到。在这种情况下,Nest 允许你通过两种方式解决提供者之间的循环依赖。在本章中,我们将介绍使用前向引用作为一种技术,以及使用 ModuleRef 类从 DI 容器中检索提供者实例作为另一种技术。
我们还将介绍如何解决模块之间的循环依赖。
warning 警告 使用“桶文件”/index.ts 文件来分组导入也可能导致循环依赖。对于模块/提供者类,应省略桶文件。例如,当导入与桶文件位于同一目录中的文件时,不应使用桶文件,即
cats/cats.controller不应导入cats来导入cats/cats.service文件。更多详情请参阅 this GitHub issue。
前向引用
前向引用允许 Nest 使用 forwardRef() 工具函数引用尚未定义的类。例如,如果 CatsService 和 CommonService 相互依赖,关系的双方都可以使用 @Inject() 和 forwardRef() 工具来解决循环依赖。否则,Nest 将无法实例化它们,因为所有必要的元数据都不可用。以下是一个示例:
info 提示
forwardRef()函数从@nestjs/common包中导入。
这涵盖了关系的一侧。现在让我们对 CommonService 做同样的操作:
warning 警告 实例化的顺序是不确定的。请确保你的代码不依赖于哪个构造函数先被调用。循环依赖依赖于具有
Scope.REQUEST的提供者可能导致未定义的依赖。更多信息可参阅 here
ModuleRef 类替代方案
使用 forwardRef() 的替代方案是重构代码,并使用 ModuleRef 类在(否则)循环关系的一侧检索提供者。了解更多关于 ModuleRef 工具类的信息 here。
模块前向引用
为了解决模块之间的循环依赖,请在模块关联的两侧使用相同的 forwardRef() 工具函数。例如:
这涵盖了关系的一侧。现在让我们对 CatsModule 做同样的操作:

