【发布时间】:2014-12-17 14:24:40
【问题描述】:
经过大量阅读和尝试Entity Framework 最新稳定版本(6.1.1)。
我正在阅读很多关于是否使用 EF6 或 EF 的存储库的矛盾,因为它的 DbContext 已经提供了一个存储库,而 DbSet 是开箱即用的 UoW .
让我先解释一下我的解决方案在项目方面包含的内容,然后我会回到矛盾之处。
它有一个类库项目和一个asp.net-mvc 项目。类库项目是数据访问,并且为 Code First 启用了 Migrations。
在我的类库项目中,我有一个通用存储库:
public interface IRepository<TEntity> where TEntity : class
{
IEnumerable<TEntity> Get();
TEntity GetByID(object id);
void Insert(TEntity entity);
void Delete(object id);
void Update(TEntity entityToUpdate);
}
下面是它的实现:
public class Repository<TEntity> where TEntity : class
{
internal ApplicationDbContext context;
internal DbSet<TEntity> dbSet;
public Repository(ApplicationDbContext context)
{
this.context = context;
this.dbSet = context.Set<TEntity>();
}
public virtual IEnumerable<TEntity> Get()
{
IQueryable<TEntity> query = dbSet;
return query.ToList();
}
public virtual TEntity GetByID(object id)
{
return dbSet.Find(id);
}
public virtual void Insert(TEntity entity)
{
dbSet.Add(entity);
}
public virtual void Delete(object id)
{
TEntity entityToDelete = dbSet.Find(id);
Delete(entityToDelete);
}
public virtual void Update(TEntity entityToUpdate)
{
dbSet.Attach(entityToUpdate);
context.Entry(entityToUpdate).State = EntityState.Modified;
}
}
这里有几个实体:
public DbSet<User> User{ get; set; }
public DbSet<Order> Orders { get; set; }
public DbSet<UserOrder> UserOrders { get; set; }
public DbSet<Shipment> Shipments { get; set; }
我不想重复自己,但是使用EF6,您不再传递存储库,而是使用DbContext。所以对于DI,我使用Ninject在asp-net-mvc项目中设置了以下内容:
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<ApplicationDbContext>().ToSelf().InRequestScope();
}
这将通过构造函数注入将ApplicationDbContext注入适用的上层类。
现在回到矛盾。
如果我们不再需要存储库,因为 EF 已经提供了开箱即用的存储库,我们该怎么做 Separation of Concern(标题中缩写为 SoC)?
如果我错了,现在纠正我,但听起来我只需要执行所有数据访问逻辑/计算(如添加、获取、更新、删除和一些自定义逻辑/计算(实体具体))在asp.net-mvc项目中,如果我不添加存储库。
非常感谢您对此事的任何了解。
【问题讨论】:
-
这只是你能得到多抽象的问题。 EF 上下文是 确实是一个存储库,但它是一个非常固执己见的存储库,具有自己的一组关系数据库特定方法。如果您也想将其抽象化,则必须使用您自己的通用存储库包装 EF。
-
我在网上看到的矛盾是最困扰我的。但是现在我们已经弄清楚了,我想知道要走的路是什么。克里斯普拉特用服务说。你说什么?
-
服务一直存在(并且由于领域驱动设计的影响而得到广泛普及),但我不认为它们是为了替换存储库。据我了解,它们只是常见操作和查询的外观,在大多数实现中,您会看到
IRepository被注入其中。最后,这一切都取决于您的项目范围。您需要问问自己,您选择的抽象级别对项目有多重要,以及从长远来看它将如何影响它,尤其是在可测试性和可扩展性方面。 -
您希望拥有自己的存储库接口,并依赖于它,而不是某些特定于实现的类型(如 DbContext)。
标签: c# asp.net-mvc dependency-injection ef-code-first entity-framework-6