NestJS:如何移除UserRepository构造函数的HelperService仍可使用test方法
解决方案
要实现子类仓库无需传递HelperService仍能正常调用父类方法,核心思路是让父类BaseRepository通过NestJS的依赖注入机制自动获取HelperService,同时通过反射获取子类对应的实体类,避免子类在构造函数中传递冗余参数。
步骤1:创建实体标记装饰器
首先定义一个装饰器,用于在子类仓库上标记对应的实体类,方便父类通过反射获取:
// entity-target.decorator.ts import { SetMetadata } from '@nestjs/common'; export const EntityTarget = (target: Function) => SetMetadata('entityTarget', target);
步骤2:修改BaseRepository
调整父类仓库的构造函数,移除需要子类传递的HelperService参数,改为通过依赖注入自动注入;同时利用Reflector从子类的装饰器中获取实体类,结合自动注入的EntityManager完成父类初始化:
// base.repository.ts import { Injectable, Inject, Reflector } from '@nestjs/common'; import { Repository, EntityTarget, EntityManager } from 'typeorm'; import { InjectEntityManager } from '@nestjs/typeorm'; import { HelperService } from './helper.service'; @Injectable() export class BaseRepository<E> extends Repository<E> { constructor( // 自动注入HelperService,无需子类传递 @Inject(HelperService) private readonly helperService: HelperService, // 注入Reflector用于读取装饰器元数据 private readonly reflector: Reflector, // 自动注入EntityManager @InjectEntityManager() entityManager: EntityManager, ) { // 通过反射获取子类标记的实体类 const target = reflector.get<EntityTarget<E>>('entityTarget', this.constructor); super(target, entityManager); } async createEntity(entity: E) { // 实现逻辑 } async getEntities(getEntitiesDto: GetEntitiesDto) { // 实现逻辑 } test() { // 正常调用HelperService的方法 this.helperService.someMethod(); } }
步骤3:简化UserRepository
现在子类仓库只需要用装饰器标记对应的实体类,无需编写构造函数即可完成继承:
// user.repository.ts import { Injectable } from '@nestjs/common'; import { BaseRepository } from './base.repository'; import { User } from './user.entity'; import { EntityTarget } from './entity-target.decorator'; @Injectable() // 用装饰器标记当前仓库对应的实体类 @EntityTarget(User) export class UserRepository extends BaseRepository<User> { // 无构造函数,完全满足需求 :) }
可选:若需要自定义EntityManager
如果子类需要指定特定的EntityManager,也可以保留构造函数,但仅传递EntityManager参数:
@Injectable() @EntityTarget(User) export class UserRepository extends BaseRepository<User> { constructor(@InjectEntityManager() entityManager: EntityManager) { super(entityManager); } }
注意事项
- 确保
HelperService已经在你的NestJS模块中被声明为提供者(providers数组中包含),否则无法被自动注入。 - 若使用多数据源,可在
@InjectEntityManager()中指定数据源名称,比如@InjectEntityManager('secondary')。
内容的提问来源于stack exchange,提问作者Đoàn Đức Bảo
相关产品推荐
相关产品推荐

