如何在动态Nestjs模块中导入registerAsync? [英] How to import a registerAsync in a dynamic Nestjs module?

查看:129
本文介绍了如何在动态Nestjs模块中导入registerAsync?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用高级NestJS调查动态模块: 如何构建完全动态的NestJS模块.

been looking into the dynamic modules using the Advanced NestJS: How to build completely dynamic NestJS modules.

据我所见,大多数人都使用本指南来构建同步/异步动态模块.

From what I've seen, most people use this guide to build a sync/async dynamic module.

但是我的问题是,如果我使用registerAsync方法,并且我的动态模块需要导入HttpModule,并且HttpModule的register-options由我的动态模块提供.

But my question is, that if I use the registerAsync method, and my dynamic module needs to import HttpModule, and HttpModule's register-options are provided by my dynamic module.

如何在动态模块中导入模块,其中动态模块提供选项?还是处理此问题的错误方法?如果是这样,您将如何组织它?

How do you import a module within a dynamic module, where the options are provided by the dynamic module? Or is it the wrong way to handle this issue? if so, how would you structure it?

这是代码.这实际上是本教程的复本.如您在register方法中看到的那样,它很简单-我只是传入了选项.registerAsync但是,我在弄清楚该怎么做时遇到麻烦.

Here's the code. Which is practically a carbon copy of the tutorial. As you can see in the register method, it's simple - I just pass in the options. registerAsync however, I'm having trouble figuring out what to do.

非常感谢您的帮助:)

import { Module, DynamicModule, Provider, HttpModule } from "@nestjs/common";
import { InvoicesHealth } from "./invoices/invoices.health";
import { InvoicesResolver, InvoicesService } from "./invoices";
import {
  CustomerInvoicesOptions,
  CustomerInvoicesAsyncOptions,
  CustomerInvoicesOptionsFactory,
} from "./interfaces";
import { CUSTOMER_INVOICES_OPTIONS } from "./constants";
import { createCustomerInvoicesProviders } from "./providers/customer-invoices.providers";

@Module({
  imports: [],
  controllers: [],
  providers: [InvoicesHealth, InvoicesResolver, InvoicesService],
  exports: [InvoicesHealth],
})
export class CustomerInvoicesModule {
  /**
   * Registers a configured customer-invoices Module for import into the current module
   */
  public static register(options: CustomerInvoicesOptions): DynamicModule {
    return {
      imports: [
        HttpModule.register({
          url: options.url,
          auth: {
            username: options.username,
            password: options.password,
          },
        }),
      ],
      module: CustomerInvoicesModule,
      providers: createCustomerInvoicesProviders(options),
    };
  }

  /**
   * Registers a configured customer-invoices Module for import into the current module
   * using dynamic options (factory, etc)
   */
  public static registerAsync(
    options: CustomerInvoicesAsyncOptions,
  ): DynamicModule {
    return {
      module: CustomerInvoicesModule,
      imports: options.imports || [],
      providers: [...this.createProviders(options)],
    };
  }

  private static createProviders(
    options: CustomerInvoicesAsyncOptions,
  ): Provider[] {
    if (options.useExisting || options.useFactory) {
      return [this.createOptionsProvider(options)];
    }

    return [
      this.createOptionsProvider(options),
      {
        provide: options.useClass,
        useClass: options.useClass,
      },
    ];
  }

  private static createOptionsProvider(
    options: CustomerInvoicesAsyncOptions,
  ): Provider {
    if (options.useFactory) {
      return {
        provide: CUSTOMER_INVOICES_OPTIONS,
        useFactory: options.useFactory,
        inject: options.inject || [],
      };
    }

    // For useExisting...
    return {
      provide: CUSTOMER_INVOICES_OPTIONS,
      useFactory: async (optionsFactory: CustomerInvoicesOptionsFactory) =>
        await optionsFactory.createFtNestCustomerInvoicesOptions(),
      inject: [options.useExisting || options.useClass],
    };
  }
}

推荐答案

好吧,插上一下,因为没有一个简单的答案,但是有的解决方法.

Okay, buckle in, cause there isn't an easy answer, but there are kind of ways around it.

首先,无法从另一个模块的异步注册方法调用一个模块的异步注册方法.至少不使用传入的异步配置,所以我将向您展示可以完成哪些 .

First and foremost, there's no way to call one module's asynchronous registration method from another module's asynchronous registration method. At least not using the asynchronous configuration that was passed in, so instead I'll show you what can be done.

在异步注册方法中,仍然可以使用的三个选项中最简单的一个.传递给异步配置的 imports 数组在模块中完全可用,因此您可以做类似的事情

Probably the easiest of the three options that still works with the async registration method. The imports array that is passed to the asynchronous config is completely available in the module, so you can end up doing something like

CustomerInvoicesModule.registerAsync({
  imports: [
    HttpModule.registerAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: httpConfigFactory,
    }),
    ConfigModule
  ],
  inject: [ConfigService],
  useFacotry: customerInvoicesConfigFactory,
})

这将以完整配置公开 HttpService .唯一需要了解/注意的是要确保您跟踪注册级别.

This will expose the HttpService in its full configuration. Only thing to be aware/careful of is making sure you're keeping track of the registration levels.

这很有趣.您可以按照以下方式更改异步配置选项:

This is the fun one. You can change your asynchronous config options to be something along the lines of

export interface CustomInvoiceModuleAsyncOptions {
  http: HttpModuleAsyncOptions;
  useClass?: RegularValueHere;
  useFacotry?: RegularValueHere;
  useValue?: RegularValueHere;
  inject: injectionArray;
  imports: importsArray;
}

现在,在您的 registerAsync 方法中,您可以执行

And now in your registerAsync method you can do

static registerASync(options: CustomerInvoiceModuleAsyncOptions): DynamicModule {
  return {
    module: CustomerInvoicesModule,
    imports: [HttpModule.registerAsync(options.http)]
    providers: [...this.createProvider(options)],
    exports: [...this.createProvider(options)],
  }
}

现在,这意味着配置是在模块选项的内部传递给 HttpModule 的,看起来很丑陋,但它会将选项传递给正确的模块.

Now, this means that the config is passed for the HttpModule inside of the options for your module, which kind of looks ugly, but it gets the options to the right module.

请不要直接使用 ConfgModule 并直接使用 register forRoot 方法.这样,您可以快速轻松地传递配置值.如果您不介意不使用 ConfigModule ,则非常简单.

Just don't use the ConfgModule and use the register or forRoot methods directly. This way you can pass config values down quickly and easily. Very straightforward if you don't mind not using the ConfigModule.

这篇关于如何在动态Nestjs模块中导入registerAsync?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆