You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NestJS使用useFactory()时如何获取ServiceA已有实例注入ServiceB

问题场景与需求

现有以下NestJS代码:

ServiceB(依赖ServiceA)

export class ServiceB {
  constructor(
    @Inject(ServiceA)
    private readonly serviceA: ServiceA,
  ) {}
}

ModuleA(提供并导出ServiceA)

@Module({
  providers: [ServiceA],
  exports: [ServiceA],
})
export class ModuleA {}

初始AppModule整合

@Module({
  imports: [ModuleA],
  providers: [ServiceB]
})
export class AppModule{}

现在需要给ServiceB的构造函数添加一个name参数:

export class ServiceB {
  constructor(
    @Inject(ServiceA)
    private readonly serviceA: ServiceA,
    name: string
  ) {}
}

尝试用useFactory传入参数时,手动实例化了ServiceA,导致生成第二个ServiceA实例:

@Module({
  imports: [ModuleA],
  providers: [
  {
    provide: ServiceB,
    useFactory: () => new ServiceB(
      new ServiceA(),
      'JOHN'
    )
  }
  ]
})
export class AppModule{}

疑问:如何获取已存在的ServiceA实例并注入到ServiceB中?


解决方案

利用NestJS useFactory 的 inject 配置项,让框架自动注入容器中已存在的ServiceA实例,而非手动创建。修改后的AppModule代码如下:

@Module({
  imports: [ModuleA],
  providers: [
    {
      provide: ServiceB,
      // useFactory的参数顺序需与inject数组顺序一致
      useFactory: (serviceA: ServiceA) => new ServiceB(serviceA, 'JOHN'),
      // 声明需要注入的依赖,Nest会从容器中取出对应实例传入工厂函数
      inject: [ServiceA]
    }
  ]
})
export class AppModule{}

原理说明

  • inject 数组用于声明当前useFactory依赖的提供者,Nest会从IoC容器中查找这些提供者的已存在实例。
  • useFactory 的参数顺序必须和inject数组的顺序完全对应,确保框架能正确将实例传入工厂函数。
  • 这种方式不会创建新的ServiceA实例,而是复用ModuleA中已创建并导出的单例实例。

内容的提问来源于stack exchange,提问作者Josh Chiu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 06:57:36