NestJS中如何向通用仓库(BaseRepository)注入动态实体?
问题解决步骤
1. 移除不必要的BaseRepository注入
你的AdminModule中无需将BaseRepository加入providers数组,AdminRepository作为继承自BaseRepository的具体实现类,已经自行处理了依赖注入逻辑。仅保留AdminRepository即可,Nest会自动解析其继承链的依赖。
修改后的admin.module.ts:
@Module({ controllers: [AdminController], providers: [ AdminService, AdminRepository, // 仅保留具体实现类 ], imports: [TypeOrmModule.forFeature([AdminUsers])], exports: [TypeOrmModule], }) export class AdminModule {}
2. 修正BaseRepository的设计
如果希望BaseRepository作为通用可注入类(而非仅作为基类),可以通过自定义Provider动态绑定实体类型,为每个实体创建对应的BaseRepository实例:
在admin.module.ts中添加自定义Provider:
@Module({ controllers: [AdminController], providers: [ AdminService, AdminRepository, // 为AdminUsers创建BaseRepository实例 { provide: 'ADMIN_USERS_BASE_REPO', useFactory: (dataSource: DataSource) => new BaseRepository(AdminUsers, dataSource), inject: [DataSource], }, ], imports: [TypeOrmModule.forFeature([AdminUsers])], exports: [TypeOrmModule], }) export class AdminModule {}
后续在需要注入的地方,使用@Inject('ADMIN_USERS_BASE_REPO')即可获取该实例。
3. 解决dataSource.getRepository is not a function错误
该错误源于错误地将Repository实例当作DataSource使用,需确保:
- 使用
@InjectDataSource()注入DataSource,而非@InjectRepository @InjectRepository(AdminUsers)返回的是Repository<AdminUsers>实例,不能赋值给DataSource类型变量
修正后的AdminRepository(注入正确的DataSource):
import { Injectable } from '@nestjs/common'; import { InjectDataSource } from '@nestjs/typeorm'; import { DataSource } from 'typeorm'; import { BaseRepository } from './base.repository'; import { AdminUsers } from './admin-users.entity'; @Injectable() export default class AdminRepository extends BaseRepository<AdminUsers> { constructor(@InjectDataSource() dataSource: DataSource) { super(AdminUsers, dataSource); } }
4. 适配TypeORM 0.3.x版本
TypeORM 0.3.x与@nestjs/typeorm 9.x兼容,但需注意:
- 确保
TypeOrmModule.forRoot()正确配置DataSource,实体路径或实体类配置无误 DataSource.getRepository()方法依然可用,若使用EntityManager,可替换为manager.getRepository()
完整修正代码示例
base.repository.ts
// 移除@Injectable,基类由子类负责注入依赖 export class BaseRepository<T extends UserEntityInterface> implements GenericInterface<T> { protected repository: Repository<T>; constructor(modelType: ObjectType<T>, dataSource: DataSource) { if (dataSource) { this.repository = dataSource.getRepository(modelType); } } async findAll(): Promise<T[]> { return this.repository.find(); } async save(entity: T): Promise<T> { return this.repository.save(entity); } }
admin.repository.ts
import { Injectable } from '@nestjs/common'; import { InjectDataSource } from '@nestjs/typeorm'; import { DataSource } from 'typeorm'; import { BaseRepository } from './base.repository'; import { AdminUsers } from './admin-users.entity'; @Injectable() export default class AdminRepository extends BaseRepository<AdminUsers> { constructor(@InjectDataSource() dataSource: DataSource) { super(AdminUsers, dataSource); } }
admin.module.ts
import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; import { AdminController } from './admin.controller'; import { AdminService } from './admin.service'; import AdminRepository from './admin.repository'; import { AdminUsers } from './admin-users.entity'; @Module({ controllers: [AdminController], providers: [AdminService, AdminRepository], imports: [TypeOrmModule.forFeature([AdminUsers])], exports: [TypeOrmModule], }) export class AdminModule {}
内容的提问来源于stack exchange,提问作者Anish
相关产品推荐
相关产品推荐

