在我的应用程序中,我想在整个项目中使用服务类的单个实例。服务类将由动态模块初始化。
细节
我有一个名为 LoggerModule 的模块,它有一个静态函数寄存器。我们使用此方法在应用程序模块中进行初始化,例如:LoggerModule.register(options)。在注册方法中,我们将返回一个动态模块,它将将此选项设置为自定义提供程序。 例如:
return {
module: LoggerModule,
providers: [
{
provide: CONFIG_OPTIONS,
useValue: options,
},
LoggerService,
],
exports: [LoggerService],
};
这里我们有一个 LoggerService,它注入(inject) CONFIG_OPTIONS,以便我们可以使用服务类获取选项。现在我希望能够通过将服务注入(inject)到我的类中来从项目中的任何位置访问该服务,但由于该模块不是全局的,目前我必须在我正在使用的所有模块中包含 LoggerModule.register() 。我尝试使用 @Global() 注释,但似乎不起作用。
你能建议任何方法来做到这一点吗?如果是,请与我分享一个例子?
最佳答案
要使动态模块全局化,您所需要做的就是在 @Module()
装饰器上方添加 @Global()
装饰器。与您正在使用的任何其他模块相同。 Here are the docs on it
编辑 2019 年 11 月 22 日
好吧,我尝试用所提供的内容以及我本地计算机上仍然存在的内容尽可能地模仿您的设置。我能够获得一个使用以下设置的全局模块:
配置模块(全局模块)
import { DynamicModule, Module, Provider, Global } from '@nestjs/common';
import { CONFIG_MODULE_OPTIONS } from './config.constants';
import { createConfigProvider } from './config.provider';
import { ConfigService } from './config.service';
import {
ConfigModuleAsyncOptions,
ConfigModuleOptions,
ConfigOptionsFactory,
} from './interfaces/config-options.interface';
@Global()
@Module({})
export class ConfigModule {
static forRoot(options: ConfigModuleOptions): DynamicModule {
return {
module: ConfigModule,
providers: [ConfigService, ...createConfigProvider(options)],
exports: [ConfigService],
};
}
static forRootAsync(options: ConfigModuleAsyncOptions): DynamicModule {
return {
module: ConfigModule,
imports: options.imports || [],
providers: [ConfigService, ...this.createAsyncProviders(options)],
exports: [ConfigService],
};
}
private static createAsyncProviders(
options: ConfigModuleAsyncOptions,
): Provider[] {
if (options.useExisting || options.useFactory) {
return [this.createAsyncOptionsProviders(options)];
}
if (options.useClass) {
return [
this.createAsyncOptionsProviders(options),
{
provide: options.useClass,
useClass: options.useClass,
},
];
}
throw new Error('Invalid ConfigModule configuration.');
}
private static createAsyncOptionsProviders(
options: ConfigModuleAsyncOptions,
): Provider {
if (options.useFactory) {
return {
provide: CONFIG_MODULE_OPTIONS,
useFactory: options.useFactory,
inject: options.inject || [],
};
}
return {
provide: CONFIG_MODULE_OPTIONS,
useFactory: async (optionsFactory: ConfigOptionsFactory) =>
await optionsFactory.createConfigOptions(),
inject: [options.useExisting || options.useClass || ''],
};
}
}
我设置了一个完全可重用的 Nest 模块,但放弃了这个想法,因为已经有一些配置模块了,因此所有的样板文件都是如此。
动态模块(是的,我知道它拼写错误)
import { Module } from '@nestjs/common';
import { DyanmicTestService } from './dyanmic-test.service';
import { DyanmicTestController } from './dyanmic-test.controller';
@Module({
providers: [DyanmicTestService],
controllers: [DyanmicTestController],
})
export class DyanmicTestModule {}
动态服务注入(inject)配置服务,但请注意我们此处不导入配置模块。这是因为它是全局的,一旦在应用程序模块中注册,就不需要在其他任何地方导入。
应用程序模块
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { DyanmicTestModule } from './dyanmic-test/dyanmic-test.module';
import { ConfigModule } from './config/config.module';
@Module({
imports: [
ConfigModule.forRootAsync({
useFactory: () => ({
fileName: '.env',
useProcess: false,
}),
}),
DyanmicTestModule,
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
所有这些代码can also be found on my GitHub .
关于nestjs - 如何使动态模块成为全局模块?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58948273/