NestJS 8:无需构造函数注入Service的实现方法
解决方案
你的问题根源在于:你手动new ServiceConfigurationService()时,Nest的DI容器没有参与实例的创建流程,属性注入(@Inject()装饰器标记属性)是Nest在自己创建实例后才会执行的逻辑,所以直接new的实例无法触发属性注入,导致依赖为undefined。
下面提供两种可行的解决方式:
方式一:让Nest创建实例,自动完成属性注入
- 给
ServiceConfigurationService添加@Injectable()装饰器,并用@Inject()标记要注入的npm服务属性:
import { Injectable, Inject } from '@nestjs/common'; import { NpmService } from '你的npm模块包名'; @Injectable() export class ServiceConfigurationService { @Inject(NpmService) private npmService: NpmService; async fetchConfig() { // 这里可以正常使用this.npmService获取配置数据 return { // 生成最终的配置对象 }; } }
- 在
ConfigModule.forRoot中导入npm模块,注册你的配置服务,并通过moduleRef获取实例执行配置加载:
import { ConfigModule } from '@nestjs/config'; import { NpmModule } from '你的npm模块包名'; import { ServiceConfigurationService } from './你的配置服务路径'; ConfigModule.forRoot({ ignoreEnvFile: true, isGlobal: true, imports: [NpmModule], // 导入npm模块,让DI容器能解析NpmService providers: [ServiceConfigurationService], // 注册配置服务到DI容器 load: [async (moduleRef) => { const configService = moduleRef.get(ServiceConfigurationService); return configService.fetchConfig(); }], }),
这种方式下,Nest会负责创建ServiceConfigurationService的实例,并自动完成属性注入,你无需手动new实例。
方式二:手动注入属性(无需将配置服务标记为@Injectable)
如果不想把ServiceConfigurationService做成可注入类,可以用useFactory注入npm服务,再手动赋值给实例属性:
import { ConfigModule } from '@nestjs/config'; import { NpmModule } from '你的npm模块包名'; import { ServiceConfigurationService } from './你的配置服务路径'; ConfigModule.forRoot({ ignoreEnvFile: true, isGlobal: true, imports: [NpmModule], useFactory: async (npmService: NpmService) => { const configService = new ServiceConfigurationService(); // 手动给属性赋值 configService.npmService = npmService; return configService.fetchConfig(); }, inject: [NpmService], // 声明需要注入的依赖 }),
这种方式跳过了Nest的自动注入流程,直接在工厂函数中获取依赖并手动赋值,适合不想修改ServiceConfigurationService原有结构的场景。
内容的提问来源于stack exchange,提问作者cat1197
相关产品推荐
相关产品推荐

