在我的主模块 (A) 中,我导入外部模块 (B) 及其配置:
imports: [
NestAuthModule.registerAsync({
inject: [authConfig.KEY],
useFactory: async (config: ConfigType<typeof authConfig>) => ({
google: config.google,
jwt: config.jwt,
}),
})
]
Run Code Online (Sandbox Code Playgroud)
export class NestAuthModule {
static registerAsync(options: AuthModuleAsyncOptions): DynamicModule {
return this.createModule(
this.createAsyncProviders(options),
options.imports || []
);
}
private static createModule(
providers: Provider[],
imports: Array<
Type<any> | DynamicModule | Promise<DynamicModule> | ForwardReference
>
) {
return {
module: NestAuthModule,
controllers: [AuthController],
providers: [
...providers
],
imports: [
...imports,
JwtModule.registerAsync({
inject: [AuthModuleOptions],
useFactory: async (options: AuthModuleOptions) => {
return {
secret: options.jwt.secretKey,
signOptions: {
expiresIn: options.jwt.expires,
},
};
},
}),
],
exports: [AuthModuleOptions],
};
}
private static createAsyncProviders(
options: AuthModuleAsyncOptions
): Provider[] {
if (options.useExisting || options.useFactory) {
return [this.createAsyncOptionsProvider(options)];
} else if (options.useClass) {
return [
this.createAsyncOptionsProvider(options),
{
provide: options.useClass,
useClass: options.useClass,
},
];
}
throw new Error('missing provider config');
}
private static createAsyncOptionsProvider(
options: AuthModuleAsyncOptions
): Provider {
const useFactory =
options.useFactory ??
(async (optionsFactory: AuthOptionsFactory) =>
await optionsFactory.createAuthOptions());
const inject = options.useFactory
? options.inject || []
: [options.useExisting || options.useClass];
return {
provide: AuthModuleOptions,
useFactory,
inject,
};
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,在模块 B 中,我正在使用工厂导入第三方模块,并且它需要模块 B 配置。但是,它尚不可用,因为它是异步的。它将在模块最终实例化时提供。但是,我已经在我的导入中注入了这个提供程序。所以,我收到注入错误:
[ExceptionHandler] Nest can't resolve dependencies of the JWT_MODULE_OPTIONS (?). Please make sure that the argument AuthModuleOptions at index [0] is available in the JwtModule context.
Potential solutions:
- If AuthModuleOptions is a provider, is it part of the current JwtModule?
Run Code Online (Sandbox Code Playgroud)
我很确定有解决方案,但我还没有找到。
我刚刚偶然发现了你同样的问题并找到了解决方案。您必须向子模块提供选项提供程序(在本例中为 JwtModule):
export const importAsyncModule = (
parentModule: DynamicModule,
subModule: DynamicModule,
optionsToken: InjectionToken,
) => {
const provider = parentModule.providers?.find(
(x) => (x as any)?.provide === optionsToken,
);
if (!provider)
throw new Error(`Provider for ${optionsToken.toString()} not found`);
subModule.providers = subModule.providers ?? [];
subModule.providers.unshift(provider);
parentModule.imports = parentModule.imports ?? [];
parentModule.imports.push(subModule);
return subModule;
};
Run Code Online (Sandbox Code Playgroud)
如果m是你的父模块,你会这样做:
const jwtModule = JwtModule.registerAsync({
useFactory: (opt: AuthenticationModuleOptions) => opt.jwt,
inject: [MODULE_OPTIONS_TOKEN],
});
importAsyncModule(m, jwtModule, MODULE_OPTIONS_TOKEN);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1858 次 |
| 最近记录: |