首页 > 解决方案 > 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.tsin的枚举feature-a.service.ts,出于某种原因,NestJs 试图解决所有依赖项,即使枚举通常在@Injectable提供程序和类之外。此枚举不是 featureB 的一部分,不应引发任何错误。

错误信息:

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

潜在的解决方案:

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

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

    导入:[ /* 包含依赖项的模块 */ ] })

找到的 2 个解决方案是:

那么,为什么 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 {}

标签: typescriptdependency-injectionenumsnestjs

解决方案


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

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


推荐阅读