如何在动态Nestjs模块中导入registerAsync? [英] How to import a registerAsync in a dynamic Nestjs module?
问题描述
使用高级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屋!