UserRepository为撒不需要@Injectable

UserRepository为撒不需要@Injectable

图片描述

为什么这里的 UserRepository 不需要加上 @Injectable 就可以在 databse.module 里作为 providers, 之前那些service却需要?

正在回答 回答被采纳积分+1

登陆购买课程后可参与讨论,去登陆

3回答
Brian 2024-07-27 10:04:08

Nestjs在处理Providers的这个部分的时候,会把其加入到DI系统中,由于设置了其为Gobal模块,所以导出的UserRepository也可以在其他的模块里面使用,这也是为什么没有加Injectable也可以使用的原因。


https://img1.sycdn.imooc.com/climg/66a4555a0957089512280304.jpg



关于nestjs的injectable,官方文档并没有更多原理的介绍。


可以参考:https://angular.dev/guide/di


https://v17.angular.io/guide/architecture-services


Nestjs中的很多设计思想是参考了angular



慕粉3946981 2024-07-24 19:29:21

看了下问题含义及老师的解答,感觉该同学的问题没有解答到位!

我来描述一下提问同学及老师的思路。

问题1: 为什么 UserRepository  不加 @Injectable 装饰器 可以作为一个提供者正常使用呢?

  • 提供者在模块类中有4种定义方式 分别是 类 、 { provide: token令牌, useClass: 类 } 、 {provide: token令牌, useFactory:  工厂函数} 、 {provide: token令牌 , useValue: 值}

  • 一个类添加与不添加 @Injectable 装饰器和能不能当作提供者没有关系

  • 但是添加了 @Injectable 装饰器后该类会有几个元数据 , 参考下面文件路径,从源码实现中我们得知使用了该装饰器后,这个类会有 `constants_1.INJECTABLE_WATERMARK` 和 `constants_1.SCOPE_OPTIONS_METADATA` 元数据

  • node_modules\@nestjs\common\decorators\core\injectable.decorator.js
  • 如果一个类当作提供者时没有使用 @Injectable 则该类会缺失这2个元数据,导致这个类虽然可以被nestjs当作一个提供者实例化管理起来供控制器使用(称为注入)。但是这个提供者类的构造函数中如果依赖别的提供者,nestjs就懵了,实例化这个提供者的时候不会去解析构造函数中的形参 (简单说这个提供者不能被注入)

实际的问题就是,为何没有使用 @Injectable  装饰器,该 UserRepository  类的构造函数中形参可以被 nestjs 依赖注入成功?

  • Brian #1

    花心思了,理解的很深入~~

    2024-07-27 09:54:42
Brian 2024-06-03 22:10:23

这里确实要加Injectable!这样可读性会比较好~


最好是要加上,这样就可以交给nestjs的DI系统来管理这个实例了。

为什么其他的模块可以使用?因为这个UserModule现在是一个全局模块,所以由于我们导出了UserRepository,所以在其他的模块中,可以使用它。

  • 提问者 demonCry #1

    意思是这东西可加可不加?没实际作用?


    ---


    为什么其他的模块可以使用?因为这个UserModule现在是一个全局模块,所以由于我们导出了UserRepository,所以在其他的模块中,可以使用它。” --- 我没问这问题呀,我的意思是为什么之前那些 XxxService 就要加上 @Injectable,但我们这里这个 UserRepository 就不用加上  @Injectable

    2024-06-03 22:32:54
  • Brian 回复 提问者 demonCry #2

    官方文档对于Injectable的说明不多。


    将提供者添加到模块的 providers 数组中才使得该提供者能够通过 IoC 容器进行注入,所以在providers中添加了的Service,再加Injectable,“没实际作用?”——对的。但是, 


    这个Injectable的作用有两个:1.TypeScript 发出关于类构造函数的元数据; 2. 告诉Nestjs这里这个类的实例要用单例模式,由DI系统管理,这就是IoC



    也有小伙伴给出了PR:


    https://github.com/nestjs/docs.nestjs.com/pull/2481/files?short_path=88ed06a#diff-88ed06aab2377fc1bd6e94f641c0d518a1c45be5246dec0d2ad851eb256dcf43


    PS: 不要“非黑即白”哦

    2024-06-03 23:06:17
  • 提问者 demonCry 回复 Brian #3

    我也查了下,

    https://stackoverflow.com/questions/64349628/what-is-injectable-in-nestjs

    https://stackoverflow.com/questions/74423435/is-not-injectable-decorator-required-in-providers


    貌似说的是如果要被标记@Injectable的那个类里又依赖了其它注入,就需要被标记为@Injectable

    不标记的话,那它里面依赖的注入拿到就是undefined


    但我们这里(一楼 UserRepository 那个图)的UserRepository没有标记为@Injectable但里面是 @Inject(REQUEST) 了的,但用着却没问题,这个request是成功注入了的。。。

    。。。

    嗯。。。可能是因为 request 在nestjs核心库里启动时早在IoC容器了注册了,所以即使UserRepository没有标记为@Injectable,但轮到它的时候,因为request已经在IoC里有了,所以取出来也不是undefined了

    以上仅为推测 

    2024-06-03 23:28:32
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
前端高级工程师(大前端)
  • 参与学习       297    人
  • 解答问题       366    个

全新打造“技术成长&职业破局”双高体系,深度打通“全栈 + 全流程 +多端+ 提效+AI赋能”,递进式锤炼思维与高阶技能,高效实现能力跃迁,助力成为“驾驭全局,深广兼备,打通多端全栈”的高级工程师

了解课程
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师