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
相关产品推荐
相关产品推荐

