首页 > 解决方案 > nestjs 在简单的提供者类中使用 ConfigService

问题描述

是否可以访问由简单提供程序类中的配置工厂制作的嵌套配置?

喜欢:

/*Can't use ConfigService because there is no way of injecting it seemingly*/
export const databaseProviders = [
  {
    provide: 'SEQUELIZE',
    useFactory: async () => {
      const sequelize = new Sequelize({
        host: ConfigService.get<string>('pg.host'),
        port: ConfigService.get<number>('pg.port'),
        dialect: 'postgres',
        username: ConfigService.get<string>('pg.username'),
        password: ConfigService.get<string>('pg.password'),
        database: ConfigService.get<string>('pg.database')
      });
      sequelize.addModels([
         models...
      ]);
      await sequelize.sync(
        process.env.NODE_ENV === 'developent' && {
          force: true
        }
      );
      return sequelize;
    }
  }
];

config/configuration.ts

export default () => ({
  pg: {
    host: 'localhost',
    port: 5432,
    username: process.env.NODE_ENV logic...
    password: process.env.NODE_ENV logic...
    database: process.env.NODE_ENV logic...
  }
});

root.module.ts

...
import { ConfigModule } from '@nestjs/config';
import configuration from './config/configuration';

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
      load: [configuration]
    }),
...

如果不是 - 是否可以包含ConfigService在一个简单的提供者类中,没有注释@Injectable()

我认为不是因为https://docs.nestjs.com/techniques/configuration#getting-started

使用 ConfigService# 要从我们的 ConfigService 访问配置值,我们首先需要 >inject ConfigService。与任何提供者一样,我们需要将其>包含模块 - ConfigModule - 导入将使用它的模块中(除非您将传递给 ConfigModule.forRoot() 方法的选项对象中的 isGlobal 属性设置为 true)。将其导入功能模块,如下所示。

但是,您可以基于在生产、登台、开发等之间执行一些逻辑并动态更改数据库配置,这非常聪明process.env.NODE_ENV。所以我非常希望有一个解决方案可以使它在@Injectables之外可用

我假设可以在项目的根目录中创建一个简单的 util 类来实现相同的目的,并在应用程序内部使用它。但我认为该解决方案有很多开销。

标签: typescriptconfignestjs

解决方案


您已经非常接近正确的设置了。在创建工厂提供程序时,您可以使用inject键和要注入的内容数组将依赖项注入工厂。在您的情况下,它看起来像这样:

/*Can't use ConfigService because there is no way of injecting it seemingly*/
export const databaseProviders = [
  {
    provide: 'SEQUELIZE',
    inject: [ConfigService], //no worries for imports because you're using a global module
    useFactory: async (configService: ConfigService) => {
      const sequelize = new Sequelize({
        host: configService.get<string>('pg.host'),
        port: configService.get<number>('pg.port'),
        dialect: 'postgres',
        username: configService.get<string>('pg.username'),
        password: configService.get<string>('pg.password'),
        database: configService.get<string>('pg.database')
      });
      sequelize.addModels([
         models...
      ]);
      await sequelize.sync(
        process.env.NODE_ENV === 'developent' && {
          force: true
        }
      );
      return sequelize;
    }
  }
];

推荐阅读