Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nest.js: how to override providers in an imported module?

Code example

Third party library
@Module({
    providers: [AService]
    exports: [AService]
})
export class AModule {
}

@Module({
    imports: [AModule],
    providers: [BService]
    exports: [BService]
})
export class BModule {
}
My code
@Module({
    imports: [BModule],
    providers: [CService]
})
export class CModule {
}

Question

How can I override/replace the AService provider from my code? (without third party library patching)

like image 700
Mike Avatar asked Nov 07 '19 13:11

Mike


People also ask

What is @inject in NestJS?

The @Injectable() decorator marks the CatsService class as a provider. cats.service.ts. import { Injectable } from '@nestjs/common'; import { Cat } from './interfaces/cat.interface'; @Injectable() export class CatsService { private readonly cats: Cat[] = []; findAll(): Cat[] { return this.

What is dynamic module in NestJS?

In fact, what our register() method will return is a DynamicModule . A dynamic module is nothing more than a module created at run-time, with the same exact properties as a static module, plus one additional property called module .

What is DTO NestJS?

A DTO is an object that defines how the data will be sent over the network. We could determine the DTO schema by using TypeScript interfaces, or by simple classes. Interestingly, we recommend using classes here.


1 Answers

Following on from my comment, this is how you would go about making a dynamic module with a dynamic provider


export interface ProviderInterface {
  handle(): void;
}

@Injectable()
class SomeHandlingProvider {
  constructor(@Inject('MY_DYNAMIC_PROVIDER') private readonly dynamicProvider: ProviderInterface) {}
  handle(): void {
    this.dynamicProvider.handle();
  }
}

@Module({})
export class AModule {
  public static forRoot(provider: ProviderInstance): DynamicModule {
    return {
       module: AModule,
       providers: [
         {
           provide: 'MY_DYNAMIC_PROVIDER',
           useClass: provider,
         },
         SomeHandlingProvider,
      ],
    };
  }
}

Then you can use like this


class GenericDynamicProviderExample implements ProviderInterface {
  handle(): void {
    console.log('hello');
  }
}

@Module({
  imports: [
    AModule.forRoot(GenericDynamicProviderExample),
  ],
})
export class BModule {}
like image 136
bashleigh Avatar answered Oct 25 '22 04:10

bashleigh