typescript - NestJs 在使用来自其他模块的枚举时尝试解决依赖关系
问题描述
我在理解为什么在解决依赖关系时考虑枚举时遇到了问题。
情况如下:
我有两个功能文件夹。我们称它们为 FeatureA 和 FeatureB。FeatureA 在这方面没有多大作用。此功能的最小工作示例是:
功能-a.module.ts:
import { Module } from '@nestjs/common';
import { FeatureAService } from './feature-a.service';
@Module({
providers: [FeatureAService],
})
export class FeatureAModule {}
功能-a.service.ts:
import { Injectable } from '@nestjs/common';
import { STUFF_B_ONLY } from '../FeatureB/feature-b.service';
@Injectable()
export class FeatureAService {
public doSomeStuff(): string {
return 'Doing stuff: ' + STUFF_B_ONLY.A; // <--- Problems with this line, enum
}
}
FeatureB 使用了 FeatureA 的一些功能。结果,我添加了访问它们所需的依赖项。
功能-b.module.ts:
import { Module } from '@nestjs/common';
import { FeatureAService } from '../FeatureA/feature-a.service';
import { FeatureBService } from './feature-b.service';
@Module({
providers: [FeatureAService, FeatureBService],
})
export class FeatureBModule {}
功能-b.service.ts:
import { Injectable } from '@nestjs/common';
import { FeatureAService } from '../FeatureA/feature-a.service';
export enum STUFF_B_ONLY {
A = 'a',
B = 'b',
}
@Injectable()
export class FeatureBService {
constructor(private readonly featureAService: FeatureAService) {}
public do(): void {
this.featureAService.doSomeStuff();
}
}
在 feature-b.service.ts 中,我只是doSomeStuff()
从 featureAService 调用。
但问题是:我使用来自feature-b.service.ts
in的枚举feature-a.service.ts
,出于某种原因,NestJs 试图解决所有依赖项,即使枚举通常在@Injectable
提供程序和类之外。此枚举不是 featureB 的一部分,不应引发任何错误。
错误信息:
错误:Nest 无法解析 FeatureBService (?) 的依赖关系。请确保索引 [0] 处的参数依赖项在 FeatureBModule 上下文中可用。
潜在的解决方案:
如果依赖项是提供者,它是当前 FeatureBModule 的一部分吗?
如果依赖项是从单独的@Module 导出的,那么该模块是在 FeatureBModule 中导入的吗?@模块({
导入:[ /* 包含依赖项的模块 */ ] })
找到的 2 个解决方案是:
将枚举移动到通用 .ts 文件,甚至不在模块中,但这种方法并不总是最好的,如果要添加大量不同的枚举,它可能会很拥挤
用基本字符串替换枚举值(
STUFF_B_ONLY.A
),但这种方法对我无效
那么,为什么 NestJs 试图解决对枚举的依赖关系,我错过了什么(提供/注入/导入)?或者移动到通用 .ts 文件是这里唯一的选择?
如果需要,主模块文件:
import { Module } from '@nestjs/common';
import { FeatureAModule } from './FeatureA/feature-a.module';
import { FeatureBModule } from './FeatureB/feature-b.module';
@Module({
imports: [
FeatureAModule,
FeatureBModule,
],
})
export class AppModule {}
解决方案
我相信发生这种情况的主要原因是 Nest 扫描器运行代码并查看文件的所有导入和导出,以及使用@Module()
装饰器中定义的模块元数据。在这里,由于它们之间的导入和导出,您在两个服务之间创建了循环依赖关系。有一种方法可以解决这个问题,只需要模块而不需要新文件,使用forwardRef
Nest 提供的函数,如下所示:
功能 A 模块
import { Module, forwardRef } from '@nestjs/common';
import { FeatureAService } from './feature-a.service';
import { FeatureBModule } from 'src/feature-b/feature-b.module';
@Module({
imports: [forwardRef(() => FeatureBModule)],
providers: [FeatureAService],
exports: [FeatureAService],
})
export class FeatureAModule {}
特色服务
import { Injectable } from '@nestjs/common';
import { STUFF_FROM_B } from '../feature-b/feature-b.service';
@Injectable()
export class FeatureAService {
doStuff() {
console.log('Doing stuff:\t' + STUFF_FROM_B.A );
}
}
功能 B 模块
import { Module, forwardRef } from '@nestjs/common';
import { FeatureBService } from './feature-b.service';
import { FeatureAModule } from 'src/feature-a/feature-a.module';
@Module({
imports: [forwardRef(() => FeatureAModule)],
providers: [FeatureBService],
exports: [FeatureBService],
})
export class FeatureBModule {}
功能 B 服务
import { Injectable, Inject, forwardRef } from '@nestjs/common';
import { FeatureAService } from 'src/feature-a/feature-a.service';
export enum STUFF_FROM_B {
A = 'a',
B = 'b',
}
@Injectable()
export class FeatureBService {
constructor(@Inject(forwardRef(() => FeatureAService)) private readonly featureAService: FeatureAService) {}
doStuff(): void {
this.featureAService.doStuff();
}
}
这不一定是一种不好的做法,但通常应该避免循环依赖,原因如下。大多数时候,Nest 会警告服务之间的循环依赖关系,但由于这是在文件之间,这可以解释为什么它没有像预期的那样被完全捕获。
推荐阅读
- jenkins - Jenkins 和插件升级后的 Jenkins ActiveChoiceParam 异常
- r - 将多个数据帧的手段组合成一个数据帧,同时为每个数据帧显示一个名称
- scala - 使用 Intellij 从 scala 测试链接到 Suites 类运行单个测试
- javascript - 下一次迭代开始前的 API 调用在循环中开始
- chef-infra - 如何将所有以 .txt 结尾的文件从食谱复制到厨师的节点?
- c# - 如何使用ghostscript同时创建2个pdf文件?
- powershell - NeoVim vim-devicons 未在 Windows 终端 (PowerShell) 中加载
- ios - SwiftUI:如何在用户滑动时实现分页?(之前使用的 UICollectionView -> 启用分页)
- laravel - Laravel 没有设置默认 cookie
- android - 从最近的菜单中关闭应用程序时如何销毁活动?