【问题标题】:Service Layer/Repository Pattern服务层/存储库模式
【发布时间】:2011-03-02 07:40:37
【问题描述】:
我正在使用带有 EF4 的服务层/存储库/工作单元模式构建一个 MVC 应用程序。
我对逻辑有点困惑。我知道重点是解耦系统,但我有点困惑。
因此,MVC 控制器调用服务来填充视图模型。那么可以说 MVC App 耦合到服务层了吗?
然后服务层调用存储库来获取和持久化对象。那么可以肯定地说服务层依赖于存储库吗?
存储库利用 EF4 获取数据并将数据保存到 SQL Server,因此我假设存储库依赖于 EF4,而EF4 又依赖于 SQL Server。
工作单元在哪里都适合。
请问有什么例子吗?
谢谢!!
【问题讨论】:
标签:
entity-framework-4
asp.net-mvc-3
repository-pattern
unit-of-work
service-layer
【解决方案1】:
我开始将工作单元隐藏在较低层的某个位置,但这样做是错误的。经过一些经验,我的看法是:
- 如果是单体应用 UnitOfWork 应该可以被 Controller 和更低层访问。
- 如果是分布式应用程序(UI 和 BL 在不同的服务器上),UnitOfWork 应该可以被业务层门面(远程调用的服务层)和更低层访问。
原因是提到的层定义了什么是“业务事务”=什么是当前工作单元。只有这一层知道它何时要提交对数据存储的更改。这样做允许服务组合(代码重用)。我讨论了类似的问题here 和here。
【解决方案2】:
山姆,
Julie Lerman 在 DNR tv 上做了一个很好的截屏,谈到了 this,在第 9 频道还有另一个截屏,围绕创建和测试存储库,只是 EF here。
与这些相关的一般事情是在 Nhibernate 中创建工作单元的抽象,它将是会话,在 EF 中将是您的上下文并将该会话或上下文传递到您的存储库中,作为您测试的一部分,您可以伪造连接使用字典列表。
希望这些帮助。
伊恩
【解决方案3】:
您对分层的假设是正确的。您的 EF 上下文是工作单元。通常,您将通过接口将其抽象出来,然后将构造函数注入每个存储库以进行 CRUD 操作。另一种方法是在 UoW 接口上公开您的存储库(我更喜欢前者)。无论哪种方式都可以更轻松地对每一层进行单元测试。然后,从服务层中对 UnitOfWork 的一次 Save 调用将保留所有存储库中的所有更改。
这里是a nice article on MSDN,它从单元测试的角度看待 UoW,但也涵盖了存储库。如果它从 MVC 控制器引用存储库,您将拥有另一个中间服务层。