1

以您有以下应用程序的场景为例:

  • 一个 MVC 4 Web 应用程序
  • 该应用程序通过 Entity Framework 5 与现有数据库通信(没有计划更改为另一个 ORM 或数据库平台)。
  • 应用程序与外部 SOAP Web 服务(Web 服务可能更改为 WCF)对话。

你会:

  1. 为所有 EF 实体创建一个通用存储库(例如 MyDBRepository),并为 SOAP Web 服务调用创建一个存储库(例如 MyWSRepository)。然后创建一个包含业务逻辑的服务类,使用这两个存储库来访问数据并为所有控制器的需求(MyApplicationService)实现 CRUD 方法。然后将存储库注入服务类,最后将服务类注入 MVC 控制器。

  2. 或者,您是否有一个使用 EF 生成的 DBContext 和生成的表实体(例如 MyDBService)来处理数据库查询和业务逻辑的服务类,以及另一个处理业务逻辑和 SOAP Web 服务调用的服务类(例如 MySOAPWebService)。然后将这两个服务都注入到 MVC 控制器中。

  3. 或者是其他东西。

过去我使用过选项 1。但我想知道这是否只是添加了不必要的抽象层。如果实体框架生成一个 DBContext,那么拥有一个直接使用 DBContext 实体的服务类似乎不那么复杂。

在阅读了 StackOverflow 中的几篇文章和其他问题后,似乎有一条灰线可以区分服务定位器模式和存储库模式。

你会使用哪种结构?

4

1 回答 1

1

我为每个聚合推荐一个存储库或 DAO。使这些类在构造函数(或工作单元,如果您愿意)上接收 dbContext。

然后让您的服务实现业务逻辑并使用 DAO。该服务负责实例化 DBContext(如果需要,还负责实例化事务)。然后服务调用具有相同上下文的不同 DAO。

为了更强大的解耦,我强烈建议您让服务层无法接触 DBContext。每次都强迫自己通过 DAO。

服务层也应该处理异常。在我的应用程序中,服务层只抛出两种类型的异常:用户和系统。在控制器上,我使用它们来区分可恢复的错误或其他内容。(这就是为什么您有时会看到特定错误,例如“无效订单号”或其他类似“系统中发生错误,稍后再试”)

顺便说一句,永远不要忘记使用断开连接的实体。当您调用存储库进行添加/更新时,始终假定 POCO 已断开连接并相应地使用它们。

于 2012-09-05T09:03:13.037 回答