模块的官方嵌套文档解释了全局模块和动态模块。我想知道是否可以将这两种模式结合起来?
我的用例如下:我有一个动态配置模块:
export class ConfigModule {
static forRoot(baseConfigPath: string): DynamicModule {
const providers = [{ provide: 'Config', useValue: configFactory(baseConfigPath) }];
return {
module: ConfigModule,
providers,
exports: providers,
};
}
}
Run Code Online (Sandbox Code Playgroud)
这使配置模块能够依赖于传入的基本配置路径。然后我可以在主应用程序模块中导入模块,如下所示:
@Module({
imports: [ConfigModule.forRoot(path.resolve(__dirname, '../config'))],
controllers: [AppController],
providers: [AppService],
})
export class AppModule implements NestModule {}
Run Code Online (Sandbox Code Playgroud)
这很好。但是,我确实有很多其他模块(app 模块的子模块,配置模块的兄弟模块),我也希望动态配置模块的同一个实例是可注入的。如果我能ConfigModule以某种方式将动态标记为全局会很棒- 或者有另一种方式吗?
我已经尝试使用 制作ConfigModule全局@Global,但这不起作用 - 这是一个基于由nest new以下人员创建的 nest starter 的超级最小简化示例 repo :https : //github.com/DeX3/nest-di-playground
最近我构建了类似您所描述的东西,我从nest/typeorm 中获得了灵感
@Module({})
export class LoggerModule {
static forRoot(rootNamespace: string): DynamicModule {
return {
module: LoggerModule,
imports: [LoggerCoreModule.forRoot(rootNamespace)],
};
}
}
Run Code Online (Sandbox Code Playgroud)
@Global()
@Module({})
export class LoggerCoreModule {
static forRoot(rootNamespace: string): DynamicModule {
const namespaceProvider = {
provide: LOGGER_ROOT_NAMESPACE,
useValue: rootNamespace,
};
const loggerServiceProvider: Provider = {
provide: LoggerService,
useFactory: (namespace) => new LoggerService(namespace).init(),
inject: [LOGGER_ROOT_NAMESPACE],
};
return {
module: LoggerCoreModule,
providers: [loggerServiceProvider, namespaceProvider],
exports: [loggerServiceProvider, namespaceProvider],
};
}
}
Run Code Online (Sandbox Code Playgroud)
然后,您将LoggerService在从LoggerCoreModule. 您不必导出您传递的配置,但我这样做了,因为我的非核心模块有一个forFeature需要它的静态方法(我没有粘贴我构建的整个内容)。
就像 @DeX3 指出的那样,您可以使用@Global模块装饰器来实现此行为。NestJS 文档中有关模块的部分提到了这一点:
https://docs.nestjs.com/modules
您可以通过查看一些为 NestJS 生态系统构建的第三方模块(例如 TypeOrm 包)来查看更深入/真实的示例:
https://github.com/nestjs/typeorm/blob/master/lib/typeorm-core.module.ts