为什么要使用Repository Pattern或者请给我解释一下?

我正在学习知识库模式,正在阅读知识库模式与entity framework4.1和代码优先和通用知识库模式 – entity framework,ASP.NET MVC和unit testing三angular关于他们如何实施存储库模式与entity framework。

•从上层隐藏EF
•使代码更好地testing

使代码更好testing我明白,但为什么从上层隐藏EF?

看看它们的实现,似乎只是用entity framework的一般方法来包装entity framework。 其实这是什么原因呢?

我假设是

  1. 松耦合(这就是为什么从上层隐藏EF)?
  2. 避免重复为相同的查询写同样的LINQ语句

我的理解是否正确?

如果我写一个DataAccessLayer是一个类有方法

QueryFooObject(int id) { ..//query foo from entity framework } AddFooObject(Foo obj) { .. //add foo to entity framework } ...... QueryBarObject(int id) { .. } AddBarObject(Bar obj) { ... } 

这也是一个存储库模式?

假人的解释将是伟大的:)

一件事是增加可testing性,并松散耦合到潜在的持久性技术。 但是,每个聚合根对象也会有一个存储库(例如,一个顺序可以是一个聚合根,也有命令行(不是聚合根),使域对象的持久性更加通用。

这也使得pipe理对象变得更容易,因为当你保存一个订单时,它也会保存你的子项目(可以是订单行)。

我不认为你应该。

entity framework已经是数据库的一个抽象层。 上下文使用工作单元模式,每个DBSet都是一个存储库。 在此之上添加一个存储库模式,使其远离ORM的function。

我在我的博客文章中谈到这个: http : //www.nogginbox.co.uk/blog/do-we-need-the-repository-pattern

添加自己的存储库实现的主要原因是,您可以使用dependency injection并使代码更易于testing。

EF不是非常容易testing的,但是通过一个可以注入的接口来创buildEF数据上下文的可模拟版本是相当容易的。

我在这里谈到: http : //www.nogginbox.co.uk/blog/mocking-entity-framework-data-context

如果我们不需要存储库模式来使EF可testing,那么我认为我们根本不需要它。

将查询保存在一个中心位置也是一个优势。 否则你的查询分散在四处,难以维护。

你提到的第一点:“隐藏EF”是一件好事! 例如,保存逻辑可能很难实现。 有多种策略适用于不同的场景。 特别是当涉及到相关实体也有变化的实体时。

使用存储库(与UnitOfWork结合使用)也可以集中这个逻辑。

这里有一些很好的解释video。

这张照片让人很容易理解

在这里输入图像说明

存储库系统适合testing。

一个原因是你可以使用dependency injection。

基本上你为你的仓库创build一个接口,并且当你创build这个对象的时候你可以引用它的接口。 然后,您可以稍后制作一个假对象(例如使用moq)来实现该接口。 使用类似ninject的东西,你可以将正确的types绑定到该接口。 繁荣,你刚刚取消了方程的依赖,取而代之的是可testing的东西。

这个想法是能够很容易地交换对象的实现用于testing目的希望是有道理的。

同样的原因,你不应该在你的应用程序中硬编码文件path: 松耦合和封装 。 想象一下,一个硬编码引用“c:\ windows \ fonts”的应用程序和可能导致的问题。 你不应该硬编码引用到path,所以你为什么要硬编码引用到你的持久层? 在configuration设置(或特殊文件夹或任何你的操作系统支持的)后面隐藏你的path,并隐藏你的持久性。 如果持久性问题隐藏在存储库后面,那么unit testing,部署到其他环境,交换实现以及关于域对象的理由将会更容易。

当你devise你的存储库类看起来像域对象,为所有的存储库提供相同的数据上下文,并促进工作单元的实现,存储库模式是有意义的。 请在下面find一些人为的例子。

  class StudenRepository { dbcontext ctx; StundentRepository(dbcontext ctx) { this.ctx=ctx; } public void EnrollCourse(int courseId) { this.ctx.Students.Add(new Course(){CourseId=courseId}); } } class TeacherRepository { dbcontext ctx; TeacherRepository(dbcontext ctx) { this.ctx=ctx; } public void EngageCourse(int courseId) { this.ctx.Teachers.Add(new Course(){CourseId=courseId}); } } public class MyunitOfWork { dbcontext ctx; private StudentRepository _studentRepository; private TeacherRepository _teacherRepository; public MyunitOfWork(dbcontext ctx) { this.ctx=ctx; } public StudentRepository StundetRepository { get { if(_studentRepository==null) _stundentRepository=new StundetRepository(this.ctx); return _stundentRepository; } } public TeacherRepository TeacherRepository { get { if(_teacherRepository==null) _teacherRepository=new TeacherRepository (this.ctx); return _teacherRepository; } } public void Commit() { this.ctx.SaveChanges(); } } //some controller method public void Register(int courseId) { using(var uw=new MyunitOfWork(new context()) { uw.StudentRepository.EnrollCourse(courseId); uw.TeacherRepository.EngageCourse(courseId); uw.Commit(); } } 

我知道在这里提供的答案不好,但是想要分享解释Repository Pattern在和Entity框架一起使用时的各种优点的video。 以下是youtube的链接。

https://www.youtube.com/watch?v=rtXpYpZdOzM

它还提供了有关如何正确实施Repository模式的详细信息。