NestJS中Providers是否必须使用Injectable装饰器?
你现在碰到的情况是NestJS在简单场景下的“宽松兼容”——当你的服务类没有依赖、也不需要额外配置时,即使没加@Injectable(),Nest的反射机制也能勉强创建实例并注入,但这绝对不是框架的设计规范,这个装饰器的必要性体现在以下几个核心场景:
依赖注入的核心标识
一旦你的服务需要注入其他Provider(比如数据库服务、配置服务),没有@Injectable()的话,Nest的DI容器根本无法识别这个类需要处理依赖注入,直接会抛出错误。比如给CatsService加个构造函数依赖试试,马上就会报错,只有加了装饰器,Nest才会递归解析并注入所有依赖。控制实例生命周期与元数据
@Injectable()允许你通过参数配置服务的作用域(比如{ scope: Scope.REQUEST }让每个请求创建新实例),或者添加自定义元数据。没加装饰器的话,你只能用默认的单例模式,没法调整生命周期,也没法给类附加框架能识别的元数据。规范代码与避免未来兼容问题
这是NestJS的官方约定,加@Injectable()明确告诉所有开发者这个类是一个可注入的服务,符合框架的分层设计模式。另外,现在的宽松兼容只是临时的,未来NestJS版本很可能会收紧规则,依赖这种“无装饰器也能运行”的未定义行为,升级时大概率会出问题。支持高级DI特性
当你用到工厂提供者、异步提供者、自定义token注入(比如@Inject('CUSTOM_TOKEN'))这些高级功能时,必须要有@Injectable()装饰器,否则Nest无法正确解析这些配置,根本没法正常工作。
举个实际的反例,要是你给CatsService加个依赖:
// 没加@Injectable()的话,启动直接报错 export class CatsService { constructor(private readonly databaseService: DatabaseService) {} }
这时候就必须加上@Injectable(),Nest才能识别并注入DatabaseService。
内容的提问来源于stack exchange,提问作者JoonDong

