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

NestJS模块中无法注入自定义TypeOrm仓储问题求助

解决方案

问题根因

使用useClass直接注册被@EntityRepository装饰的TypeOrm自定义仓储时,Nest独立实例化的类缺少TypeOrm内部注入的EntityManager、数据源等核心依赖,调用父类Repository的方法时会触发内部属性未定义的报错。单元测试使用的内存仓储未继承TypeOrm的Repository类,不需要这些底层依赖,因此运行正常。

修复方案

方案一:通过工厂方法获取TypeOrm托管的自定义仓储实例

修改workout.module.ts中的provider注册逻辑,使用useFactory从TypeOrm连接中获取已经完成初始化的自定义仓储实例:

import { Connection } from 'typeorm';

@Module({
  imports: [TypeOrmModule.forFeature([Workout])],
  providers: [
    {
      provide: EXERCISE_REPOSITORY,
      useFactory: (connection: Connection) => connection.getCustomRepository(TypeOrmExerciseRepository),
      inject: [Connection]
    },
    {
      provide: WORKOUT_REPOSITORY,
      useFactory: (connection: Connection) => connection.getCustomRepository(TypeOrmWorkoutRepository),
      inject: [Connection]
    },
    WorkoutResolver,
    WorkoutService,
  ],
})
export class WorkoutModule {}

方案二:组合而非继承TypeOrm Repository

重写自定义TypeOrm仓储,不继承Repository类,改为注入标准TypeOrm仓储实现功能,原有模块的provider注册逻辑无需修改:

// typeorm-workout.repository.ts
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Workout } from '../entities/workout.entity';
import { WorkoutRepository } from './workout-repository.interface';

@Injectable()
export class TypeOrmWorkoutRepository implements WorkoutRepository {
  constructor(
    @InjectRepository(Workout)
    private readonly baseRepo: Repository<Workout>
  ) {}

  async findById(workoutId: string): Promise<Workout> {
    return this.baseRepo.findOne(workoutId);
  }

  // 其余接口实现均调用baseRepo的对应方法即可
}

两种方案都可以保证生产环境的仓储实例拥有完整的TypeOrm操作能力,同时保持服务与仓储实现的解耦,原有单元测试逻辑无需做任何调整。

内容的提问来源于stack exchange,提问作者A Mehmeto

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 04:30:01