【问题标题】:NestJs tries to resolve dependencies when using enum from other moduleNestJs 在使用来自其他模块的枚举时尝试解决依赖关系
【发布时间】:2026-01-14 21:55:01
【问题描述】:

我无法理解为什么在解决依赖关系时会考虑枚举。

情况如下:

我有两个功能文件夹。我们称它们为 FeatureA 和 FeatureB。 FeatureA 在这方面没有多大作用。此功能的最小工作示例是:

feature-a.module.ts:

import { Module } from '@nestjs/common';
import { FeatureAService } from './feature-a.service';

@Module({
    providers: [FeatureAService],
})
export class FeatureAModule {}

feature-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 的一些功能。因此,我添加了访问它们所需的依赖项。

feature-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 {}

feature-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 中,我只需从 featureAService 调用 doSomeStuff()

但问题是:我在feature-a.service.ts 中使用来自feature-b.service.ts 的枚举,并且出于某种原因,即使枚举通常在@Injectable 提供程序和类之外,NestJs 也会尝试解决所有依赖关系。此枚举不是 featureB 的一部分,不应引发任何错误。

错误信息:

错误:Nest 无法解析 FeatureBService (?) 的依赖关系。 请确保索引 [0] 处的参数依赖项是 在 FeatureBModule 上下文中可用。

可能的解决方案:

  • 如果依赖是提供者,它是当前 FeatureBModule 的一部分吗?

  • 如果依赖项是从单独的@Module 导出的,那么该模块是在 FeatureBModule 中导入的吗? @模块({

    imports: [ /* 包含依赖的模块 */ ] })

找到的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 {}

【问题讨论】:

    标签: typescript dependency-injection enums nestjs


    【解决方案1】:

    我认为发生这种情况的主要原因是 Nest 扫描器会运行代码并查看文件的所有导入和导出,以及使用 @Module() 装饰器中定义的模块元数据。在这里,由于它们之间的导入和导出,您已经在两个服务之间创建了循环依赖关系。有一种方法可以解决这个问题,只需要模块而不需要新文件,使用 Nest 提供的 forwardRef 函数,如下所示:

    功能 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 会警告服务之间的循环依赖关系,但由于这是在文件之间,这可以解释为什么它没有像预期的那样被完全捕获。

    【讨论】:

    • 我不知道forwardRef() 实用程序。对其进行了测试,似乎可以正常工作。 :) 但是对于这种情况,移动到不同的(通用)文件可能比使用forwardRef() 更好(因为它是可以避免的)?我有点担心滥用这个实用程序。
    • 就个人而言,我会转移到一个专门的枚举文件和其他此类文件。 forwardRef主要用于引用循环依赖的服务和模块。
    • 好吧。感谢您的时间和投入。 :)