有关 nestjs 的循环引用问题;

2022-08-15 10:19:04 +08:00
 oppddd

我有几个 module ,service 引用结构如下

A -> B -> A. 也就是说 A ,B 有相互引用关系;这样会导致循环引用问题; nestjs 编译会报错;

通过查询,了解到的解决方法有两种;

  1. 抽离一个 module C ,然后引入 Service A ,B ; 在 A ,B controller 中直接引入 Service C ;那样 service A ,B 就会是单纯业务逻辑,不会引发 circular dependencies
  2. 是使用 forwardref

这两种方法都可以;但是有点疑问,希望能得到解惑;谢谢了;

方法 1: 会多出一个 module ; 那如果有关联关系的业务实体,是不是都会引发一个新的 module 来避免 circular dependencies

那我是不是可以把所有的 service 集中在一起 Module Common ,然后供 controller 消费,就能避免在 service 中消费其他 service 引发 circular dependencies ;这样的话 Module Common 就变成了垃圾桶了,啥都放在里面; 

方法 2: 有可能发生未知错误;不知道引用关系到底是什么样子的;跟 nestjs 的依赖注入 设计有点相反;不太想用

4300 次点击
所在节点    Node.js
5 条回复
ZxBing0066
2022-08-15 10:31:06 +08:00
最简单的方法是合并 A 和 B 为一个模块

理论上极少数情况会出现循环引用的情况,如果一旦出现基本说明两个模块耦合严重,这种情况合并就是了,至于你说的方法 1 其实是合并后的抽离可复用代码。
otakustay
2022-08-15 10:40:03 +08:00
抽一个 C ,然后 A 和 B 的 Service (不是 Controller )都注入 C (不要直接 import ,走 NestJS 的 Injectable ),就像你 Service 会用 HttpService 一样搞
oppddd
2022-08-15 19:45:18 +08:00
楼上两位朋友说的都对,我再补充一点, 还有一种方法,不引入 service 而是引入 reponstory ,
Sunzehui
2022-08-17 16:22:53 +08:00
遇到过这种问题,使用的第一种方案,用 forwardref 我没跑成功。
看你说的只注入 repository ,我想是脱离问题本质了,本来就是想方便复用,这样相当于重写一遍逻辑了(也可以把数据库操作扩充到原有 repository 上,算是复用代码了吧)。
另外你说的抽到 Common 里,那为什么不一开始全写 Common 里,那样模块化就没有意义了,也不循环引用了。
zhennann
2022-09-09 12:39:23 +08:00
控制反转有两种实现方案:依赖注入和依赖查找。nestjs 采用依赖注入导致模块之间代码耦合严重。本来模块化的意义就是实现代码隔离,但是 nestjs 实际上确是模块之间代码相互引用。因此,在 node 生态中,最便利的是依赖查找方案,可以实现模块之间的完全隔离,也就不会出现类似循环引用的问题,更不需要提出一个中间模块。可以参见 CabloyJS 全栈框架的《 Bean 容器与控制反转》: https://cabloy.com/zh-cn/articles/bean.html

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/872886

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX