【发布时间】:2020-11-25 20:03:54
【问题描述】:
我的 DbRepository 类如下:
public class DbRepository<TEntity, TDbContext> : IRepository<TEntity>
where TEntity : class, IEntity
where TDbContext : DbContext
{
protected readonly TDbContext dbContext;
/// <summary>
/// Initializes a new instance of the <see cref="DbRepository{TEntity}" /> class.
/// </summary>
public DbRepository(TDbContext dbContext)
{
this.dbContext = dbContext;
}
/// <inheritdoc/>
public async Task<TEntity> AddAsync(TEntity entity)
{
ObjectCheck.EntityCheck(entity, $"{nameof(TEntity)} missing.");
await dbContext.Set<TEntity>().AddAsync(entity);
await dbContext.SaveChangesAsync();
return entity;
}
/// <inheritdoc/>
public virtual async Task<TEntity> GetAsync(object primaryKey)
{
ObjectCheck.PrimaryKeyCheck(primaryKey, $"primaryKey <= 0 in {nameof(IRepository<TEntity>)}");
return await dbContext.Set<TEntity>().FindAsync(primaryKey);
}
/// <inheritdoc/>
public virtual IQueryable<TEntity> GetAll(Expression<Func<TEntity, bool>> filter = null)
{
return (filter != null ? dbContext.Set<TEntity>().Where(filter) : dbContext.Set<TEntity>());
}
/// <inheritdoc/>
public virtual async Task<TEntity> GetSingleAsync(Expression<Func<TEntity, bool>> filter)
{
return await dbContext.Set<TEntity>().SingleOrDefaultAsync(filter);
}
/// <inheritdoc/>
public virtual async Task<TEntity> UpdateAsync(TEntity entity)
{
ObjectCheck.EntityCheck(entity, $"{nameof(TEntity)} missing.");
dbContext.Set<TEntity>().Update(entity);
await dbContext.SaveChangesAsync();
return entity;
}
/// <inheritdoc/>
public virtual async Task DeleteAsync(object primaryKey)
{
var entityToBeDeleted = await GetAsync(primaryKey);
ObjectCheck.EntityCheck(entityToBeDeleted, $"{nameof(TEntity)} missing.");
dbContext.Set<TEntity>().Remove(entityToBeDeleted);
await dbContext.SaveChangesAsync();
}
}
我的界面如下:
public interface IRepository<TEntity>
where TEntity : class, IEntity
{
Task<TEntity> GetAsync(object primaryKey);
IQueryable<TEntity> GetAll(Expression<Func<TEntity, bool>> filter = null);
Task<TEntity> GetSingleAsync(Expression<Func<TEntity, bool>> filter);
Task<TEntity> AddAsync(TEntity entity);
Task<TEntity> UpdateAsync(TEntity entity);
Task DeleteAsync(object primaryKey);
}
如何在启动时将它们注册为作用域并告诉每个类创建存储库?那么我可以在这些存储库上编写测试吗?
我有 4 个模型,我不想为每个模型创建存储库类和接口它们总是相同的 - 简单的 crud 操作。相反,我希望工厂创建它们。
public class RepositoryFactory
{
public static TRepository GetRepositoryInstance<T, TRepository>()
where TRepository : IRepository<T>, new()
{
return new TRepository();
}
}
我得到的错误是类型必须是引用类型才能在泛型类型或方法 IRepository 中用作参数 TEntity
【问题讨论】:
-
DI 用于创建您的实例。当你想用工厂创建时,你最好注册工厂。在您的情况下,我将通过将静态方法转换为实例方法并在启动时在 DI 中注册 RepositoryFactory: services.AddSingleton(new RepositoryFactory());单例,因为工厂模式是创建模式,您使用工厂来创建您的存储库,而不是 DI。另一种注册方法是将工厂放在一边并这样做: services.AddScoped
, Repository ();并为所有 4 个实体执行此操作。总而言之,我不推荐任何这些解决方案
标签: c# generics repository factory