我有像这样的 Typeorm 通用存储库
import { Injectable } from '@nestjs/common'
import { IGenericRepository } from '../abstracts/generic-repository'
import { Repository } from 'typeorm'
@Injectable()
export class GenericRepository<T> implements IGenericRepository<T> {
private _repository: Repository<T>;
constructor(repository: Repository<T>) {
this._repository = repository;
}
getAll(): Promise<T[]> {
return this._repository.find()
}
findById(id: any): Promise<T> {
return this._repository.findOneBy(id)
}
create(item: T): Promise<T> {
return this._repository.save(item)
}
update(id: string, item: T) {
return this._repository
}
}
我想使用这个存储库作为其他服务的提供者。 例如我想在用户模块中使用它
import { Module } from '@nestjs/common';
import { User } from '../entity/user.entity';
import { GenericRepositoryModule, GenericRepository } from '@app/common';
import { Repository } from 'typeorm'
@Module({
imports: [
GenericRepositoryModule
],
providers: [ // I think something is wrong here
{
provide: 'userGenericRepository',
useFactory: (genericRepository: GenericRepository<User>, user: User) => new genericRepository(Repository(user)),
inject: [GenericRepository,User]
}
],
})
export class UserModule { }
但这不起作用,有错误
我认为这个提供商
有问题那么,我该如何解决这个问题?
问题是您正在向他们自己的提供商提供
GenericRepository
。
解决这个问题的方法是:
export function createRepositoryToken(entity: any): string {
return `${entity}__generic_repository_token`;
}
export function createGenericRepositoryProvider(entity: any): Provider {
return {
provide: createRepositoryToken(entity),
useFactory: (manager: EntityManager) => {
return new GenericRepository(new Repository(entity, manager));
},
inject: [EntityManager],
};
}
export const InjectRepo = (entity: any) =>
Inject(createRepositoryToken(entity));
@Module({
imports: [],
providers: [
createGenericRepositoryProvider(User);
]
})
export class UserModule {}
一个更简洁的选择是像这样编写模块:
// user.providers.ts
export UserRepositoryProvider = createGenericRepositoryProvider(User);
并在您的模块中使用它
@Module({
imports: [],
providers: [
UserRepositoryProvider;
]
})
export class UserModule {}
@Injectable()
export class UserService {
constructor(@InjectRepo(User) private readonly repository: GenericRepository<User>)
}
就完成了。
更新(奖励):
您还可以创建一个模块来轻松提供通用存储库。
export type GenericRepositoryModuleOptions = {
entities: any[];
};
@Module({})
export class GenericRepositoryModule {
static forFeature(options: GenericRepositoryModuleOptions): DynamicModule {
const repositoryTokens = this.createRepositoryTokens(options);
const repositoryProviders = this.createRepositoryProviders(options);
return {
module: GenericRepositoryModule,
providers: repositoryProviders,
exports: repositoryTokens,
};
}
private static createRepositoryTokens(options: GenericRepositoryModuleOptions) {
return options.entities.map(entity => createRepositoryToken(entity));
}
private static createRepositoryProviders(
options: GenericRepositoryModuleOptions
): Provider[] {
return options.entities.map((entity) =>
createGenericRepositoryProvider(entity)
);
}
}
它通过像这样的提供商的一些更改来解决
import { Module } from '@nestjs/common';
import { User } from '../entity/user.entity';
import { GenericRepository } from '@app/common';
import { Repository } from 'typeorm'
import { Repository, EntityManager } from 'typeorm'
@Module({
imports: [],
providers: [ // I think something is wrong here
{
provide: 'userGenericRepository',
useFactory: (manager: EntityManager) => new genericRepository(new Repository(User, manager)),
inject: [EntityManager]
}
],
})
export class UserModule { }