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

如何在Nest.js中动态注入不同的提供者?

解决NestJS中动态指定QueueService依赖提供者的问题

下面提供三种可行的实现方案,可根据业务场景选择:

方案一:创建独立的QueueService实例(推荐,符合NestJS依赖注入规范)

通过为不同的Pubsub提供者创建专属的QueueService实例,控制器直接注入对应实例使用。

步骤1:修改AppModule配置

在providers中添加两个QueueService的自定义提供者,分别绑定不同的Pubsub:

import { PubsubService } from '@myorg/queue'
import { QueueService } from './queue.service';

@Module({
  imports: [
    ConfigModule.forRoot({
      validationSchema: Joi.object({
        SHARED_RESOURCES_PROJECT_ID: Joi.string().required()
      })
    })
  ],
  controllers: [AppController],
  providers: [
    {
      provide: 'PUBSUB',
      useValue: new PubsubService()
    },
    {
      provide: 'INTEGRATION_PUBSUB',
      useValue: new PubsubService({ projectId: process.env.SHARED_RESOURCES_PROJECT_ID })
    },
    // 绑定默认QueueService到PUBSUB
    {
      provide: 'DEFAULT_QUEUE_SERVICE',
      useClass: QueueService,
      inject: ['PUBSUB']
    },
    // 绑定集成用QueueService到INTEGRATION_PUBSUB
    {
      provide: 'INTEGRATION_QUEUE_SERVICE',
      useClass: QueueService,
      inject: ['INTEGRATION_PUBSUB']
    }
  ]
})
export class AppModule {}

步骤2:修改控制器注入两个QueueService实例

@Controller()
export class AppController {
  constructor(
    @Inject('DEFAULT_QUEUE_SERVICE') private readonly defaultQueueService: QueueService,
    @Inject('INTEGRATION_QUEUE_SERVICE') private readonly integrationQueueService: QueueService
  ) {}

  @Post()
  async create() {
    // 使用绑定PUBSUB的QueueService
    return this.defaultQueueService.sendMessage(...)
  }

  @Patch()
  async update() {
    // 使用绑定INTEGRATION_PUBSUB的QueueService
    return this.integrationQueueService.sendMessage(...)
  }
}

原QueueService无需修改,保持现有代码即可。


方案二:让QueueService支持动态切换Pubsub

在QueueService内部注入所有Pubsub实例,通过方法参数指定使用哪个提供者。

修改QueueService代码

@Injectable()
export class QueueService {
  private pubsubMap: Record<string, PubsubService>;

  constructor(
    @Inject('PUBSUB') private readonly defaultPubsub: PubsubService,
    @Inject('INTEGRATION_PUBSUB') private readonly integrationPubsub: PubsubService
  ) {
    this.pubsubMap = {
      'PUBSUB': defaultPubsub,
      'INTEGRATION_PUBSUB': integrationPubsub
    };
  }

  async sendMessage(payload, providerKey: string = 'PUBSUB'): Promise<void> {
    const pubsub = this.pubsubMap[providerKey];
    if (!pubsub) {
      throw new Error(`Unknown Pubsub provider: ${providerKey}`);
    }
    return pubsub.sendMessage(payload);
  }
}

控制器调用时指定提供者

@Controller()
export class AppController {
  constructor(private readonly queueService: QueueService) {}

  @Post()
  async create() {
    return this.queueService.sendMessage(..., 'PUBSUB')
  }

  @Patch()
  async update() {
    return this.queueService.sendMessage(..., 'INTEGRATION_PUBSUB')
  }
}

方案三:使用工厂模式动态创建QueueService

创建工厂类,根据传入的提供者key返回对应的QueueService实例。

步骤1:创建QueueService工厂

@Injectable()
export class QueueServiceFactory {
  constructor(
    @Inject('PUBSUB') private readonly defaultPubsub: PubsubService,
    @Inject('INTEGRATION_PUBSUB') private readonly integrationPubsub: PubsubService
  ) {}

  createQueueService(providerKey: string): QueueService {
    let pubsub: PubsubService;
    switch(providerKey) {
      case 'PUBSUB':
        pubsub = this.defaultPubsub;
        break;
      case 'INTEGRATION_PUBSUB':
        pubsub = this.integrationPubsub;
        break;
      default:
        throw new Error(`Unknown Pubsub provider: ${providerKey}`);
    }
    return new QueueService(pubsub);
  }
}

步骤2:模块中注册工厂

@Module({
  // ... 其他配置
  providers: [
    // ... 原有PUBSUB、INTEGRATION_PUBSUB提供者
    QueueServiceFactory
  ]
})
export class AppModule {}

步骤3:控制器中使用工厂创建实例

@Controller()
export class AppController {
  constructor(private readonly queueFactory: QueueServiceFactory) {}

  @Post()
  async create() {
    const queueService = this.queueFactory.createQueueService('PUBSUB');
    return queueService.sendMessage(...)
  }

  @Patch()
  async update() {
    const queueService = this.queueFactory.createQueueService('INTEGRATION_PUBSUB');
    return queueService.sendMessage(...)
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 22:56:29