3

我已经阅读了很多关于存储库模式和服务层的作用的文章,并且我(我认为)很清楚两者之间的区别。但是一个简单的问题现在让我摸不着头脑。

我知道数据访问层如何负责...访问数据,因此典型的存储库可能具有插入、更新、删除和保存等方法(基本的 CRUD 方法)。服务层包含所有业务内容、验证、发送电子邮件和所有爵士乐,我读到的一件事是服务层不应该重复存储库方法,因为这种设置不会增加任何价值。

但我的问题在于“添加”方法。假设我有一个供应商类,我想将特定供应商添加到我的供应商列表中。用户通过 UI(MVC Web 应用程序)输入供应商信息,然后Create调用控制器方法。

现在控制器应该如何处理才能持久化这个供应商?

  • 直接存储库
  • 服务层

由于纯存储库实现除了持久化实体之外不会做任何其他事情,如果我有一些验证和/或业务规则,我显然应该使用服务层。但是如果我不应该控制器直接处理存储库?在我看来,这似乎打破了架构的分层性质。控制器正在跳过服务层并与持久层对话。

假设我想安全起见并使用服务层(因为我可能有验证和其他与供应商打交道相关的东西)。我最终会得到:

  • AddSupplier 方法
  • 一个 UpdateSupplier 方法
  • DeleteSupplier 方法

这是我一开始不想要的,因为现在我有一个与服务层和数据访问层的一对一方法映射。

所以我的问题是:(添加 | 更新 | 删除)供应商方法应该去哪里?

另外,是否可以绕过服务层并从控制器直接与存储库层对话?

4

1 回答 1

2

我认为您的问题没有一个明确的答案,因为有很多因素需要考虑(正如您所指出的,这也有点自相矛盾)。我相信最好的实现有几个重要的部分。

  1. 一个非常通用的存储库,它与数据源交互并执行插入、更新、删除基本 CRUD 方法(正如您所指出的)。最佳情况下,这将以通用方式完成,因此您的交互在您的应用程序中是一致的。例如,返回单个实体的方法,如T Single(Func<T, bool> where).

  2. 包含封装业务功能的方法的特定业务服务。这些服务是唯一允许与存储库交互的服务。除了 'Hello World' 样式的示例之外,这些方法不会简单地添加或删除项目,而是可能与 2 个或更多实体交互并执行复杂的业务逻辑。例如,服务方法可能是“CreateAccount”或“RemmoveBlogPost”,这无疑需要的不仅仅是添加单个实体或删除一个实体。

  3. “瘦”和“哑”控制器几乎不执行任何逻辑,而只是根据需要调用服务方法。控制器只是使用变量并返回响应。但是,它们可能会在每个控制器动作中调用各种服务方法。服务方法的混合和重用导致高效和 DRY 编码实践。

当您意识到您想在应用程序的另一部分执行全部或部分方法时,这种方法会显示出它的优势。例如,如果您正在构建一个博客应用程序,您可能会发现该应用程序面向公众的一面需要一种查看单个博客文章的方法,而管理员方面也需要它。在这个简单的示例中,将在每个控制器中重复按 Id 返回博客文章,但是,如果您创建了一个名为 getBlogPostById 的服务方法,则可以在两个控制器中重用该逻辑。

于 2012-08-14T00:27:22.323 回答