nestjs - 如何使动态模块成为全局模块?

标签 nestjs

在我的应用程序中,我想在整个项目中使用服务类的单个实例。服务类将由动态模块初始化。

细节

我有一个名为 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/

相关文章:

javascript - 如何用 Jest 模拟 S3?

具有多种策略的 Nestjs 护照身份验证

javascript - 用值初始化 Guard

typescript - NestJs:为什么 monorepo 模式只打包根应用程序,

javascript - NestJS - 注入(inject)的服务在构造函数中未定义

javascript - 嵌套 JS 同一个提供者的两个实例

nestjs - NestJS 中的环境变量在每个模块中都不可见?

mysql - NestJs Typeorm 会删除外键列,即使设置为非空

node.js - 如何使用 nestjs/mongoose 在模式类中定义 mongoose 方法?

node.js - 如何使用nestjs redis微服务?