Nest Js пытается разрешить зависимости при использовании enum из другого модуля - PullRequest
0 голосов
/ 24 февраля 2020

У меня проблемы с пониманием того, почему enum учитывается при разрешении зависимостей.

Ситуация следующая:

У меня есть две папки функций. Давайте назовем их 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 я просто вызываю doSomeStuff() из featureAService.

Но проблема в том, что я использую enum из feature-b.service.ts в feature-a.service.ts и по какой-то причине Nest Js пытается разрешить все зависимости, даже если enum находится за пределами @Injectable провайдера и класса в целом. Это перечисление не является частью featureB и не должно выдавать никаких ошибок.

Сообщение об ошибке:

Ошибка: Nest не может разрешить зависимости FeatureBService (?). Убедитесь, что зависимость аргумента по индексу [0] доступна в контексте FeatureBModule.

Потенциальные решения:

  • Если зависимость является поставщиком, является ли она частью текущий FeatureBModule?

  • Если зависимость экспортируется из отдельного модуля @Module, импортируется ли этот модуль в FeatureBModule? @Module ({

    импорт: [/ * Модуль, содержащий зависимость * /]})

Найдено 2 решения:

  • Переместить enum в файл generi c .ts, даже не в модуле, но этот подход не всегда лучший, он может быть переполнен, если будет добавлено множество различных перечислений

  • Замените значение enum (STUFF_B_ONLY.A) на базовую c строку, но этот подход для меня недопустим

Итак, ПОЧЕМУ Гнездо Js пытается разрешить зависимости от enum и я что-то пропустил (предоставить / ввести / импортировать)? Или переход к универсальному c .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 {}

1 Ответ

1 голос
/ 24 февраля 2020

Я полагаю, что основная причина, по которой это происходит, заключается в том, что сканер Nest просматривает код и просматривает все операции импорта и экспорта файла, а также работу с метаданными модуля, определенными в декораторах @Module(). Здесь вы создали круговую зависимость между двумя службами из-за импорта и экспорта между ними. Есть способ исправить это, используя только модули и не требуя нового файла, используя функцию forwardRef, предоставляемую Nest, например:

Модуль Feature 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 {}

Сервис Feature A

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 предупреждает о циклических зависимостях между службами, но поскольку это происходит между файлами, это объясняет, почему он не был полностью перехвачен, как ожидалось.

...