【问题标题】:Entity Framework 4 and Repository Pattern实体框架 4 和存储库模式
【发布时间】:2011-02-18 05:47:37
【问题描述】:

有人能解释一下使用这种模式的好处吗?

我的意思是 EF 不是某种意义上的存储库吗?你不能只查询容器并返回那些对象吗?

我看到很多关于 POCO、AutoMapper、依赖注入、服务层、IoC 的讨论。我只是将一堆东西混合在一起,还是它们都相关?

谁能给我解释一下?

另外,这一切如何与 MVC.net、ViewModels 与 DataModels 结合在一起?

谢谢, 山姆

【问题讨论】:

    标签: entity-framework-4 dependency-injection repository-pattern poco


    【解决方案1】:

    那里有一堆随机问题,所以我会给出一堆随机答案:

    • 存储库(由 Martin Fowler 定义)为“使用类似于集合的接口访问域对象在域和数据映射层之间进行调解”
    • EF是一个ORM,即数据映射层
    • 是的,您可以查询 EF 容器并返回对象,但是消费者“知道太多”底层持久性机制,而它不应该知道/关心 - 因此是存储库模式
    • POCO 是一种用于将对象从持久性元数据中释放出来的技术(默认使用 EF 代码生成)。它们还允许您的 POCO 兼作您的域模型。
    • ViewModel 由 MVC 视图使用。
    • AutoMapper 用于将 ViewModel 轻松转换为领域模型。
    • 服务层在控制器和存储库之间提供了一个中间地带 - 专门用于 IQueryable<T> 存储库,以将查询具体化为具体序列(例如 ICollection<T>)。
    • IoC 用于解耦组件之间的依赖关系,从而提供良好/干净的架构和最高的可测试性(您可以将 Mock 存储库传递到控制器,以隔离方式对它们进行单元测试)。

    第 3 条请求详细说明

    示例控制器没有存储库:

    public class ProductsController
    {
       public ActionResult GetProduct(int productId)
       {
           Product p;
    
           using (var ctx = new MySecretContextWhichIsNowExposed())
           {
              p = ctx.Products.SingleOrDefault(x => x.ProductId == productId);
           }
    
           return View(p);
       }
    }
    

    以上问题:

    1. 控制器直接使用实体框架对象上下文,这意味着 Web 应用程序知道它,并且需要对 System.Data.Entity 的引用。
    2. 几乎不可能进行单元测试。您将针对实际数据库进行测试,这使其成为集成测试而不是单元测试。
    3. 控制器具有“如何检索单个产品”的逻辑,但它不应该 - 这是域/存储库逻辑。

    示例控制器 WITH 存储库(和 IoC):

    public class ProductsController
    {
       private readonly IProductsRepository _repo;
    
       public ProductsController(IProductsRepository repo)
       {
          _repo = repo;
       }
    
       public ActionResult GetProduct(int productId)
       {
           Product p = _repo.FindById(productId);
           return View(p);
       }
    }
    

    为什么上面更好:

    1. 控制器不知道 EF。不依赖 System.Data.Entity。
    2. 控制器不知道存储库的实现,它通过接口工作。
    3. 控制器不提供有关如何检索产品的逻辑,只提供 id。
    4. 2 行简单代码。
    5. 测试单元 = 小菜一碟。通过 ctor 中的 MockProductRepository 并处理它(可以实现为内存中的列表)。

    【讨论】:

    • @RPM1984 - 您能否详细说明 #3:italic_是的,您可以查询 EF 容器并返回对象,但是消费者对底层持久性机制“了解太多”,当它不应该知道/关心 - 因此存储库模式?_italic
    • @RPM1984 - 所有这些技术/技术是否相关?
    • @Sam Striano - 是的,它们都相关。但有些不是 .NET 特定的(POCO - Java 有 POJO,DI/IoC 是通用编程原则,存储库/服务层也是如此)。
    • @RPM1984 - 存储库代码在哪里?在与 EF 相同的组件中?你能给我举一个分层方法的例子吗?
    • @Sam Striano - 举个例子涉及的太多了,我建议你有一个谷歌 - “ef4 repository poco”。但是是的,它应该与 EF 在同一个程序集中 - “MyCompany.Project.Data”程序集。
    猜你喜欢
    • 2010-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多