Home > database >  How can I dynamically inject different providers with Nest.js?
How can I dynamically inject different providers with Nest.js?

Time:12-06

I'm facing the following issue. I have a service used by a controller. The service (in the snippets below QueueService) injects a provider imported from a package. I aim to reuse the QueueService across the controller methods, but I also need to dynamically specify which provider QueueService should use.

My question is, how can I achieve this behaviour?

import { PubsubService } from '@myorg/queue'

@Module({
  imports: [
    ConfigModule.forRoot({
        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 })
    }
  ]
})
export class AppModule {}

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

  @Post()
  async create() {
    ...

    // here I want to use queueService with `PUBSUB` injected
    return this.queueService.sendMessage(...)
  }

  @Patch()
  async update() {
    ...

    // here I want to use queueService with `INTEGRATION_PUBSUB` injected
    return this.queueService.sendMessage(...)
  }
}
@Injectable()
export class QueueService {
  constructor(
    // how can I dynamically change `@Inject('PUBSUB')` to `@Inject('INTEGRATION_PUBSUB')`?
    @Inject('PUBSUB') private readonly pubsubService: PubsubService
  ) {}

  async sendMessage(payload): Promise<void> {
    return this.pubsubService.sendMessage(payload)
  }
}

CodePudding user response:

dynamic inject is not possible after object(in this case controller) created . so you have two option

1- create two QueueService (one for PUBSUB and another for INTEGRATION_PUBSUB) and inject both to controller. use those in your controller functions. (i recommend this)

2- inject both PUBSUB and INTEGRATION_PUBSUB into QueueService and pass another param in sendMessage function . so check this param to choose between PUBSUB and INTEGRATION_PUBSUB

  • Related