NestJS中使用forwardRef()后仍存在模块循环依赖返回undefined的问题
我之前在做NestJS项目时也踩过这个一模一样的坑,明明加了forwardRef()却还是碰到循环依赖导致的undefined,咱们一步步来排查可能的问题:
双向配置forwardRef是核心前提
很多人容易犯的错是只在其中一个模块里加了forwardRef()导入另一个模块,这肯定不行!必须在TransactionsModule和InvoicesModule的imports数组里都配置对应的forwardRef:
比如InvoicesModule的配置也要跟上:@Module({ imports: [forwardRef(() => TransactionsModule)], controllers: [InvoicesController], providers: [InvoicesService, TenantConnectionProvider], exports: [InvoicesService] // 别忘了导出要被依赖的服务 }) export class InvoicesModule {}服务注入时必须配合forwardRef
光模块配置了还不够,在服务的构造函数里注入依赖服务时,必须用@Inject(forwardRef(() => 目标服务))的方式,两边的服务都要这么做:
比如在TransactionsService里注入InvoicesService:@Injectable() export class TransactionsService { constructor( @Inject(forwardRef(() => InvoicesService)) private readonly invoicesService: InvoicesService ) {} }反过来InvoicesService注入TransactionsService也要用完全一样的写法。
务必检查模块的exports配置
一定要确认你要跨模块注入的服务,已经在对应模块的exports数组里声明了。比如如果TransactionsService要被InvoicesModule使用,那TransactionsModule里必须把TransactionsService加到exports里,不然就算模块导入了,也拿不到对应的服务实例,自然会返回undefined。避开初始化阶段的过早调用
要是你在服务的constructor或者模块的onModuleInit钩子里面直接调用依赖服务的方法,这时候依赖可能还没完成初始化,很大概率会拿到undefined。可以把这类逻辑移到onApplicationBootstrap钩子(这个钩子会在所有模块都初始化完成后执行),或者改用异步的方式处理。
按照这几步逐一排查,基本能解决大部分用了forwardRef()还出现undefined的循环依赖问题,你可以先对照自己的代码检查下哪一步没做到位~
内容来源于stack exchange

