typescript - NestJS Injicera Factory-leverantör i en annan Factory


Jag har granskat frågorna här, och de hjälpte inte med mitt problem:

  • NestJS - Att injicera en fabrikleverantör i en annan leverantör fungerar inte

Jag vill skapa en asynkron leverantör som hämtar konfigurationer från ett fjärrförråd, vilket jag implementerade så här:


import { Injectable, Provider } from '@nestjs/common';
@Injectable()
export class ApiConfigService {
  private config: any;

  public async init() {
    await new Promise((resolve) => setTimeout(resolve, 500));

    this.config = {
      data: 3,
    };
  }
}

export const API_CONFIG_FACTORY = 'API_CONFIG_FACTORY';

const createApiConfigFactory = () => {
  return {
    generate: async function () {
      const apiConfigService = new ApiConfigService();
      await apiConfigService.init();
      return apiConfigService;
    },
  };
};

export const ApiConfigFactory: Provider = {
  provide: API_CONFIG_FACTORY,
  useFactory: createApiConfigFactory,
};

api-config.module.ts:

import { Module } from '@nestjs/common';
import { ApiConfigFactory } from './api-config.service';

@Module({
  imports: [],
  providers: [ApiConfigFactory],
  exports: [ApiConfigFactory],
})
export class ApiConfigModule {}

Jag vill också använda den modulen i NestJS ThrottlerModule, men när jag försöker göra det:

import { Module } from '@nestjs/common';
import { ThrottlerModule } from '@nestjs/throttler';
import { ApiConfigModule } from './api-config/api-config.module';
import { ApiConfigFactory } from './api-config/api-config.service';

@Module({
  imports: [
    ApiConfigModule,
    ThrottlerModule.forRootAsync({
      imports: [ApiConfigModule],
      inject: [ApiConfigFactory],
      useFactory: (config: any) => {
        console.log('@config');
        console.log(config);

        return {
          ttl: config.get('throttle_api_ttl'),
          limit: config.get('throttle_api_limit'),
        };
      },
    }),
  ],
})
export class AppModule {}

Det ger detta fel:

Error: Nest can't resolve dependencies of the THROTTLER:MODULE_OPTIONS (?). Please make sure that the argument [object Object] at index [0] is available in the ThrottlerModule context.

Potential solutions:
- If [object Object] is a provider, is it part of the current ThrottlerModule?
- If [object Object] is exported from a separate @Module, is that module imported within ThrottlerModule?
  @Module({
    imports: [ /* the Module containing [object Object] */ ]
  })

Hur kan jag framgångsrikt implementera en asynkron konfigurationsleverantör som jag skulle kunna injicera i ThrottlerModule?

Tack på förhand för din tid!

Svar #1

För att få din exakta kod att fungera, ersätt bara ApiConfigFactory med API_CONFIG_FACTORY, och ange din config-tjänst som mottagits :

ThrottlerModule.forRootAsync({
  imports: [ApiConfigModule],
  inject: [API_CONFIG_FACTORY],                // -> Provider token HERE
  useFactory: (config: ApiConfigService) => {  // -> ApiConfigService HERE
    return {
      ttl: config.get('throttle_api_ttl'),
      limit: config.get('throttle_api_limit'),
    };
  },
}),

Men du kan också förenkla din kod på följande sätt:

api-konfig.modul.ts:

@Module({
  imports: [],
  providers: [
    {
      provide: ApiConfigService,
      useFactory: async () => {
        const apiConfigService = new ApiConfigService();
        await apiConfigService.init();
        return apiConfigService;
      },
    },
  ],
  exports: [ApiConfigService],
})
export class ApiConfigModule {}

och sedan i app.module.ts imports :

ThrottlerModule.forRootAsync({
  imports: [ApiConfigModule],
  inject: [ApiConfigService],
  useFactory: (config: ApiConfigService) => {
    return {
      ttl: config.get('throttle_api_ttl'),
      limit: config.get('throttle_api_limit'),
    };
  },
}),

Relaterade artiklar