You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NestJS依赖注入报错:无法解析UserService依赖,排查循环引用问题

NestJS依赖注入报错:"Nest can't resolve dependencies of the UserService (?)"

我在使用NestJS开发时遇到以下报错,怀疑是DI循环引用问题。删除UserModule仅使用AuthModule时一切正常,相关模块代码如下,请指出错误并提供解决方案。

模块代码

user.module.ts

import { Module } from '@nestjs/common';
import { UserService } from './user.service';
import { UserController } from './user.controller';
import { PrismaService } from 'src/prisma/prisma.service';

@Module({
  controllers: [UserController],
  providers: [UserService, PrismaService],
})
export class UserModule {}

user.service.ts

import { Injectable } from '@nestjs/common';
import type { PrismaService } from 'src/prisma/prisma.service';
import type { CreateUserDto } from './dto/create-user.dto';
import { hash } from 'argon2';

@Injectable()
export class UserService {
  constructor(private readonly prisma: PrismaService) {}

  async create(createUserDto: CreateUserDto) {
    const { password, ...user } = createUserDto;
    const hashedPassword = await hash(password);
    return await this.prisma.users.create({
      data: {
        password: hashedPassword,
        ...user,
      },
    });
  }

  async findByEmail(email: string) {
    this.prisma.users.findUnique({
      where: {
        email,
      },
    });
  }
}

auth.module.ts

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { AuthController } from './auth.controller';
import { UserService } from 'src/user/user.service';
import { PrismaService } from 'src/prisma/prisma.service';

@Module({
  controllers: [AuthController],
  providers: [AuthService, UserService, PrismaService],
})
export class AuthModule {}

auth.service.ts

import {
      ConflictException,
      forwardRef,
      Inject,
      Injectable,
    } from '@nestjs/common';
    import type { CreateUserDto } from 'src/user/dto/create-user.dto';
    import { UserService } from 'src/user/user.service';
    
    @Injectable()
    export class AuthService {
      constructor(
        @Inject(forwardRef(() => UserService))
        private readonly userService: UserService,
      ) {}
    
      registerUser(createUserDto: CreateUserDto) {
        const user = this.userService.findByEmail(createUserDto.email);
        if (user) throw new ConflictException('User already exists!');
        return this.userService.create(createUserDto);
      }
    }

app.module.ts

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { PrismaService } from './prisma/prisma.service';
import { AuthModule } from './auth/auth.module';
import { UserModule } from './user/user.module';

@Module({
  imports: [AuthModule, UserModule],
  controllers: [AppController],
  providers: [AppService, PrismaService],
})
export class AppModule {}

报错信息

ERROR [ExceptionHandler] Nest can't resolve dependencies of the UserService (?). Please make sure that the argument Function at index [0] is available in the AuthModule context.

Potential solutions:
- Is AuthModule a valid NestJS module?
- If Function is a provider, is it part of the current AuthModule?
- If Function is exported from a separate @Module, is that module imported within AuthModule?
  @Module({
    imports: [ /* the Module containing Function */ ]
  })

Error: Nest can't resolve dependencies of the UserService (?). Please make sure that the argument Function at index [0] is available in the AuthModule context.

Potential solutions:
- Is AuthModule a valid NestJS module?
- If Function is a provider, is it part of the current AuthModule?
- If Function is exported from a separate @Module, is that module imported within AuthModule?
  @Module({
    imports: [ /* the Module containing Function */ ]
  })

问题分析与解决方案

错误原因

  1. 重复注册服务导致依赖冲突:AuthModule直接将UserService声明为本地provider,但UserService属于UserModule。当AppModule同时导入两个模块时,Nest会尝试在AuthModule内实例化UserService,却找不到其依赖的PrismaService(AuthModule未正确关联PrismaService的注入逻辑)。
  2. 滥用forwardRef:当前代码不存在AuthService与UserService的双向依赖,不需要使用forwardRef,反而导致Nest无法正常解析依赖类型。
  3. 异步方法逻辑漏洞:UserService.findByEmail未返回异步查询结果,导致AuthService中的用户存在判断完全失效。
  4. PrismaService重复注册:多个模块重复声明PrismaService,不符合Nest的单例服务设计原则。

修复步骤

1. 重构UserModule,导出UserService

修改user.module.ts,将UserService加入exports数组,让其他模块通过导入UserModule来复用服务:

import { Module } from '@nestjs/common';
import { UserService } from './user.service';
import { UserController } from './user.controller';
import { PrismaService } from 'src/prisma/prisma.service';

@Module({
  controllers: [UserController],
  providers: [UserService, PrismaService],
  exports: [UserService] // 导出UserService供外部模块使用
})
export class UserModule {}

2. 修正AuthModule,导入UserModule而非重复声明服务

删除AuthModule中直接声明的UserService和PrismaService,改为导入UserModule:

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { AuthController } from './auth.controller';
import { UserModule } from 'src/user/user.module';

@Module({
  controllers: [AuthController],
  providers: [AuthService],
  imports: [UserModule] // 导入UserModule以使用其导出的UserService
})
export class AuthModule {}

3. 移除AuthService中不必要的forwardRef

由于不存在循环依赖,直接注入UserService即可:

import { ConflictException, Injectable } from '@nestjs/common';
import type { CreateUserDto } from 'src/user/dto/create-user.dto';
import { UserService } from 'src/user/user.service';

@Injectable()
export class AuthService {
  constructor(private readonly userService: UserService) {} // 移除forwardRef

  async registerUser(createUserDto: CreateUserDto) {
    const user = await this.userService.findByEmail(createUserDto.email); // 加上await处理异步结果
    if (user) throw new ConflictException('用户已存在!');
    return this.userService.create(createUserDto);
  }
}

4. 修复UserService的异步方法返回值

findByEmail方法遗漏return,导致无法获取查询结果:

import { Injectable } from '@nestjs/common';
import type { PrismaService } from 'src/prisma/prisma.service';
import type { CreateUserDto } from './dto/create-user.dto';
import { hash } from 'argon2';

@Injectable()
export class UserService {
  constructor(private readonly prisma: PrismaService) {}

  async create(createUserDto: CreateUserDto) {
    const { password, ...user } = createUserDto;
    const hashedPassword = await hash(password);
    return await this.prisma.users.create({
      data: {
        password: hashedPassword,
        ...user,
      },
    });
  }

  async findByEmail(email: string) {
    // 添加return返回异步查询结果
    return this.prisma.users.findUnique({
      where: {
        email,
      },
    });
  }
}

5. 优化PrismaService的注册(可选但推荐)

创建独立的PrismaModule,统一管理PrismaService的注入:

// src/prisma/prisma.module.ts
import { Module } from '@nestjs/common';
import { PrismaService } from './prisma.service';

@Module({
  providers: [PrismaService],
  exports: [PrismaService]
})
export class PrismaModule {}

然后在UserModule中导入PrismaModule:

// user.module.ts
import { Module } from '@nestjs/common';
import { UserService } from './user.service';
import { UserController } from './user.controller';
import { PrismaModule } from 'src/prisma/prisma.module';

@Module({
  controllers: [UserController],
  providers: [UserService],
  exports: [UserService],
  imports: [PrismaModule]
})
export class UserModule {}

内容的提问来源于stack exchange,提问作者Ba Loc Dang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 10:46:02