I am trying to do something fancy: a DynamicModule that chooses a Controller/Providers depending on a provider. The provider reads a config in a DB at onModuleInit, so there is no way to hard-code its values.
It is similar to this issue: https://github.com/nestjs/nest/issues/601 which was never answered...
I have tried a few approaches and the closest I have got is this:
export class FancyModule implements DynamicModule {
public module: Type<FancyModule>;
public controllers: Type<unknown>[];
public providers: Provider<unknown>[];
constructor (
@Inject(StartupConfigService) private readonly startup: StartupConfigService,
) {
this.module = FancyModule;
if (startup.featureFlagEnabled) {
this.controllers = [ FancyFeatureController ];
this.providers = [ FancyFeatureService ];
} else {
this.controllers = [ ErrorController ];
this.providers = [];
}
}
}
Second approach:
app.module.ts
@Module({
imports: [
StartupConfigModule.register(startupConfigOption),
FancyModule.registerAsync({
imports: [StartupConfigModule],
useFactory: function (startupConfigService: StartupConfigService) {
return startupConfigService.config
},
inject: [StartupConfigService],
}),
],
})
fancy.module.ts
export class FancyModule {
static registerAsync (config: IAppConfig): DynamicModule {
if (config.featureFlagEnabled) {
return {
module: FancyModule,
controllers: [ FancyFeatureController ],
providers: [ FancyFeatureService ],
};
} else {
return {
module: FancyModule,
controllers: [ ],
providers: [ ],
};
}
}
}
This injects as expected but the controllers and providers are never spun up. Is the meta-data evaluated before the constructor? Is that a bug?