Nest не может разрешить зависимости AuthService
Я слежу за документацией, представленной здесь
https://docs.nestjs.com/techniques/authentication
Чтобы иметь более быструю поддержку, я создал репозиторий git с проблемой
https://github.com/Sano123456/nestjs-jwt
node -v -> v10.15.2
npm -v -> 6.14.6
nest -v -> 7.4.1
Первая проблема: в AuthModule, если я сделаю, как описано в документации, и просто импортирую UserModule, он вернет мне ошибку циклической зависимости между UserModule и AuthModule
@Module({
imports:[
UsersModule,
PassportModule
],
providers: [AuthService],
controllers: [AuthController],
exports:[AuthService, LocalStrategy]
})
export class AuthModule {}
ошибка:
[ExceptionHandler] Nest cannot create the AuthModule instance.
The module at index [0] of the AuthModule "imports" array is undefined.
Potential causes:
- A circular dependency between modules. Use forwardRef() to avoid it. Read more: https://docs.nestjs.com/fundamentals/circular-dependency
- The module at index [0] is of type "undefined". Check your import statements and the type of the module.
Scope [AppModule -> UsersModule] +6ms
Возможное решение в массиве импорта AuthModule вместо UserModule put forwardRef(() => UsersModule), это фактически удаляет ошибку, но не уверен, что это правильный путь
Вторая проблема: он говорит, что не может найти класс LocalStrategy, даже если он присутствует и объявлен в AuthModule
[ExceptionHandler] Nest cannot export a provider/module that is not a part of the currently processed module (AuthModule). Please verify whether the exported LocalStrategy is available in this particular context.Is LocalStrategy part of the relevant providers/imports within AuthModule?
Возможное решение прямо сейчас у меня нет решения, я просто удаляю его, чтобы понять, в чем проблема
Третья проблема: после удаления LocalStrategy,
[ExceptionHandler] Nest can't resolve dependencies of the AuthService (?). Please make sure that the argument dependency at index [0] is available in the AuthModule context.
Potential solutions:
- If dependency is a provider, is it part of the current AuthModule?
- If dependency is exported from a separate @Module, is that module imported within AuthModule?
@Module({
imports: [ /* the Module containing dependency */ ]
})
+1ms
Error: Nest can't resolve dependencies of the AuthService (?). Please make sure that the argument dependency at index [0] is available in the AuthModule context.
кто-нибудь решил эту проблему?
3 ответа
У вас есть циклическая зависимость, потому что ваши UsersModule и AuthModule импортируют друг друга. Поэтому у вас есть 2 варианта решения этой проблемы.
Во-первых, сделать прямую ссылку, которая позволит создавать оба модуля одновременно, а после сборки передать требуемую ссылку. Делается это так:
@Module({
imports: [
forwardRef(() => UsersModule),
],
...
})
export class AuthModule {}
// And the same for your UsersModule
@Module({
imports: [
forwardRef: (() => AuthModule),
],
})
export class UsersModule {}
Второй вариант - убрать зависимости друг от друга. Это не всегда возможно, и, судя по названиям ваших модулей, я бы сказал, что это невозможно. Вы не хотите, чтобы модуль auth имел доступ к базе данных и службам пользовательского модуля и т. Д. Вне модуля users. Но я дам вам несколько советов по наследованию модулей.
Модули в nestjs строятся асинхронно. Это означает, что они должны быть структурированы как каскадное дерево, в котором один модуль должен импортировать все остальные. Что-то линейное будет выглядеть так
AppModule <= CatModule <= PawsModule
Другой пример - двойной импорт
<= CatModule
AppModule <= PawsModule
<= DogModule
В приведенном выше примере модуль paws создается один раз и импортируется в модуль cat и dog. Это означает, что модуль "лапы" будет построен раньше, чем модуль "кошка и собака".
Итак, чтобы объяснить свою ошибку, вам нужно подумать с точки зрения линейного кода и того, как дерево импорта модулей будет совместно использовать модули, которые импортируют друг друга. Поскольку они импортируют друг друга, nest не может решить, что создать первым, поэтому для обратной передачи потребуется ссылка, отсюда и функция. Я всегда представлял себе функцию прямого рефлекса контейнера, которая говорит: "Эй, подожди секунду" (это лист бумаги с надписью "UsersModule"), затем поворачивается, немного махает руками, повернувшись спиной, затем поворачивается вокруг и заменяет бумажку на UsersModule!
Вторая проблема заключается в том, что вы никогда не создавали провайдера для LocalStrategy
. Его нет в AuthModule, поэтому его нельзя ни импортировать в AuthService, ни экспортировать из AuthModule!
** РЕШЕНИЕ проблемы "не удается разрешить зависимости" **
Для первой и второй проблемы окончательным решением является использование @Inject(forwardRef(() => AuthService)) в UserService вот пример
@Injectable()
export class UserService {
constructor(
@InjectRepository(User) private readonly UserRepository: Repository<User>,
private readonly config: ConfigService,
@Inject(forwardRef(() => AuthService)) //<---
private readonly authService: AuthService,
) {
}
То же самое и в AuthService
@Injectable()
export class AuthService {
private client: any;
constructor(
@Inject(forwardRef(() => UserService))//<--- here
private readonly userService: UserService,
@InjectConfig() private readonly config,
) {
}
В AuthModule и UserModule вам все равно нужно использовать forwardRef
Я никогда раньше не использовал это решение и никогда не нуждался в нем, но это решило мою проблему.
Что касается LocalStrategy, поместите его в массив поставщиков модуля
Для меня было недостаточно просто использовать forwardRef для обеих служб, как в ответе Сано; Мне также пришлось пересылать ссылку на оба круговых зависимых модуля.
В обоих сервисах:
https://docs.nestjs.com/fundamentals/circular-dependency#forward-reference
import { forwardRef, Inject } from '@nestjs/common';
...
@Inject(forwardRef(() => UserService))`
В обоих модулях:
https://docs.nestjs.com/fundamentals/circular-dependency#module-forward-reference
import { forwardRef } from '@nestjs/common';
...
imports: [
forwardRef(() => UsersModule),
],