【发布时间】:2014-02-04 20:10:36
【问题描述】:
我想使用存储库模式并创建一个通用的可重用组件。我注意到,当我使用以下接口和基类时,我发现有时我没有实现某些方法(例如,有时我从不需要调用 getAll() 来检索所有对象的列表,不需要该操作在我的特定课程申请中)。
public interface IRepository<TEntity, TId>
{
void Delete(TEntity entity);
TEntity Get(TId id);
IEnumerable<TEntity> GetAll();
void Save();
void Update(TEntity entity);
void Create(TEntity entity);
}
我决定将胖接口分成更小的迷你接口。然后,我想出了一些可以组合在一起的小实现,以获得您的存储库实现所需的确切内容。以下是我想出的。任何人都可以就以下解决方案存在的问题给我建议吗?
public abstract class Entity<TId> : IEntityIdentity<TId>
{
public TId Id { get; set; }
}
public interface IEntityIdentity<TId>
{
TId Id { get; set; }
}
public interface IDeleteRepository<TEntity, TId> where TEntity : Entity<TId>
{
void Delete(TEntity entity);
}
public class DeleteRepository<TEntity, TId> : IDeleteRepository<TEntity, TId> where TEntity : Entity<TId>
{
private readonly DbContext _dbContext;
public DeleteRepository(DbContext dbContext)
{
_dbContext = dbContext;
}
public void Delete(TEntity entity)
{
_dbContext.Set<TEntity>().Remove(entity);
}
}
public interface ISaveRepository<TEntity, TId> where TEntity : Entity<TId>
{
void Save(TEntity entity);
}
public class SaveRepository<TEntity, TId> : ISaveRepository<TEntity, TId> where TEntity : Entity<TId>
{
private readonly DbContext _dbContext;
public SaveRepository(DbContext dbContext)
{
_dbContext = dbContext;
}
public void Save(TEntity entity)
{
_dbContext.SaveChanges();
}
}
public interface IUpdateRepository<TEntity, TId> where TEntity : Entity<TId>
{
void Update(TEntity entity);
}
public class UpdateRepository<TEntity, TId> : IUpdateRepository<TEntity, TId> where TEntity : Entity<TId>
{
private readonly DbContext _dbContext;
public UpdateRepository(DbContext dbContext)
{
_dbContext = dbContext;
}
public void Update(TEntity entity)
{
_dbContext.Entry(entity).State = EntityState.Modified;
}
}
public interface IGetRepository<TEntity, TId> where TEntity : Entity<TId>
{
TEntity Get(TId id);
}
public class GetRepository<TEntity, TId> : IGetRepository<TEntity, TId> where TEntity : Entity<TId>
{
private readonly DbContext _dbContext;
public GetRepository(DbContext dbContext)
{
_dbContext = dbContext;
}
public TEntity Get(TId id)
{
return _dbContext.Set<TEntity>().Find(id);
}
}
public interface IGetAllRepository<TEntity, TId> where TEntity : Entity<TId>
{
IEnumerable<TEntity> GetAll();
}
public class GetAllRepository<TEntity, TId> : IGetAllRepository<TEntity, TId> where TEntity : Entity<TId>
{
private readonly DbContext _dbContext;
public GetAllRepository(DbContext dbContext)
{
_dbContext = dbContext;
}
public IEnumerable<TEntity> GetAll()
{
return _dbContext.Set<TEntity>();
}
}
public interface ICreateRepository<TEntity, TId> where TEntity : Entity<TId>
{
void Create(TEntity entity);
}
public class CreateRepository<TEntity, TId> : ICreateRepository<TEntity, TId> where TEntity : Entity<TId>
{
private readonly DbContext _dbContext;
public CreateRepository(DbContext dbContext)
{
_dbContext = dbContext;
}
public void Create(TEntity entity)
{
_dbContext.Set<TEntity>().Add(entity);
}
}
public class RepositoryCombiner<TEntity, TId> : IGetRepository<TEntity, TId>, IGetAllRepository<TEntity, TId> where TEntity : Entity<TId>
{
private readonly IGetRepository<TEntity, TId> _getRepository;
private readonly IGetAllRepository<TEntity, TId> _getAllRepository;
public RepositoryCombiner(IGetRepository<TEntity, TId> getRepository, IGetAllRepository<TEntity, TId> getAllRepository)
{
_getRepository = getRepository;
_getAllRepository = getAllRepository;
}
public TEntity Get(TId id)
{
return _getRepository.Get(id);
}
public IEnumerable<TEntity> GetAll()
{
return _getAllRepository.GetAll();
}
}
【问题讨论】:
-
我将两者混合使用。我有单独的角色(接口)并在一个存储库上实现所需的功能,而不是每个角色都有一个存储库。
-
让我想起了 Udi Dahan 的明确角色:infoq.com/presentations/Making-Roles-Explicit-Udi-Dahan 为什么不呢,但是用 C# IMO 这样的语言来表达有点冗长和笨拙
标签: design-patterns domain-driven-design repository-pattern ddd-repositories