nurikabe
nurikabe

Reputation: 4010

Can't use custom provider

I'm trying to inject a custom provider as per the documentation:

https://docs.nestjs.com/fundamentals/custom-providers

My service:

@Injectable({scope: Scope.REQUEST})
export class ReportService implements OnModuleInit {
  private readonly reportRepository: Repository<Report>;

  constructor(
    public config: ConfigService,
    private readonly moduleRef: ModuleRef,
    @Inject('CONNECTION') connection: Connection,
  ) {
    console.log(connection);
  }
  ...

app.module.ts:

const connectionProvider = {
  provide: 'CONNECTION',
  useValue: connection,
};

@Module({
  imports: [
    ReportModule,
    ...
  ],
  providers: [connectionProvider],
  controllers: [AppController],
})
export class AppModule implements NestModule {

Doing so results in:

Error: Nest can't resolve dependencies of the ReportService (ConfigService, ModuleRef, ?). Please make sure that the argument at index [2] is available in the ReportModule context.

What am I missing?

Upvotes: 0

Views: 1324

Answers (1)

KenavR
KenavR

Reputation: 3899

If a provider should be available outside of the module you defined it in, you need to add it to exports in the module definition (app.module). The other module (report.module) using it needs to add the module to its imports definition.

app.module.ts

const connectionProvider = {
  provide: 'CONNECTION',
  useValue: Connection,
};

@Module({
  imports: [
    ReportModule,
    ...
  ],
  providers: [connectionProvider],
  exports: ['CONNECTION'],
  controllers: [AppController],
})
export class AppModule implements NestModule {}

report.module.ts

@Module({
  imports: [
    AppModule
  ],
  providers: [],
  controllers: [],
})
export class ReportModule implements NestModule {}

In your case, this produces a circular dependency which needs to be resolved.

Since app.module seems to be your core module you could make it global but you still need to export the provider.

Alternatively, I found it to be a good practice to not define any providers in app.module and use DynamicModule (e.g. forRoot and forFeature static initiator functions) to only instantiate what is needed, but that seem to be outside of this question.

Upvotes: 2

Related Questions