NestJS中providers与imports的区别是什么?
我正在学习NestJS的认证教程。
在auth/auth.module.ts文件中:
import { JwtModule } from '@nestjs/jwt' ... @Module({ imports: [ UsersModule, PassportModule, JwtModule.register({ secret: jwtConstants.secret, signOptions: { expiresIn: '60s' }, }), ], providers: [AuthService, LocalStrategy, JwtStrategy], exports: [AuthService], })
可以看到JwtModule被配置在imports数组下。
在auth/auth.service.ts文件中,JwtService被注入:
... import { JwtService } from '@nestjs/jwt'; @Injectable() export class AuthService { constructor( private usersService: UsersService, private jwtService: JwtService ) {} ...
根据NestJS文档:
在Module部分:
providers - 将由Nest注入器实例化的提供者,至少可以在当前模块内共享
imports - 导入模块的列表,这些模块导出当前模块所需的提供者
在Providers部分:
提供者是Nest中的核心概念。许多基础Nest类都可以作为提供者,例如服务、仓库、工厂、工具类等。提供者的核心思想是可以作为依赖被注入,这意味着对象之间可以建立各种关系,而对象实例的关联工作大部分可以委托给Nest运行时系统。
我仍有疑问:既然providers和imports都用于依赖注入,二者之间到底有什么区别?
核心区别解析
作用对象不同
providers是直接声明当前模块要创建实例的自定义类/提供者,比如你自己编写的AuthService、LocalStrategy,Nest会在当前模块的注入器中实例化它们,供模块内部使用或导出给其他模块。imports是引入已封装完成的外部模块,这些模块已经通过exports暴露了可供外部使用的提供者。比如JwtModule内部已经定义并导出了JwtService,导入该模块后,就能直接在当前模块的类中注入JwtService,无需自行声明它为provider。复用与封装逻辑不同
如果某个服务仅在当前模块使用,或是模块内的核心业务服务,就放在providers里;若需要被其他模块复用,可将其加入当前模块的exports数组,其他模块通过imports导入你的模块就能使用该服务。imports主要用于复用第三方模块或自定义的公共模块,比如UsersModule导出了UsersService,导入后就能在AuthService中直接注入使用,无需重复创建UsersService实例。实例管理方式不同
providers中的类,Nest会在当前模块的注入器中创建实例(全局模块除外),不同模块若声明了同一个provider,会生成独立的实例。
通过imports引入的模块,其导出的提供者会被加入当前模块的注入器,且这些提供者的实例由原模块的注入器管理(若为单例模式,整个应用仅存在一个实例),比如JwtModule.register()配置后,全应用的JwtService实例是同一个。
简单来说:providers是自己造“工具”,imports是借别人封装好的“工具包”,工具包里的工具可以直接拿来用。
内容的提问来源于stack exchange,提问作者yoty66

