一起使用 Repository factory 和 repository factor 设计模式

Use Repository factory and repository factor design pattern together

我的 DbRepository class 如下:

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);
   }
    

如何在启动时将它们注册为作用域并告诉每个 class 创建存储库?那么我可以在这些存储库上编写测试吗?

我有 4 个模型,我不想为每个模型创建存储库 classes 和接口它们总是相同的 - 简单的 crud 操作。相反,我希望工厂创建它们。

public class RepositoryFactory
    {
        public static TRepository GetRepositoryInstance<T, TRepository>()
         where TRepository : IRepository<T>, new()
        {
            return new TRepository();
        }
    }

我得到的错误是 The type must be a reference type order to use as parameter TEntity in the generic type or method IRepository

它给你这个错误是因为在 IRepository 接口中你告诉 T 必须是 class(引用类型)并且它必须实现 IEntity 接口。

在工厂里你没有说 none 个。

可能你必须这样写:

public class RepositoryFactory
{
    public static TRepository GetRepositoryInstance<T, TRepository>()
          where TRepository : IRepository<T>, new()
          where T : class, IEntity
    {
        return new TRepository();
    }
}