c# - 如何正确使用仓库模式?

标签 c# .net asp.net asp.net-mvc repository-pattern

我想知道应该如何对存储库进行分组?就像我在 asp.net mvc 和我的书中看到的示例一样,它们基本上每个数据库表使用一个存储库。但这似乎有很多存储库,导致您以后不得不调用许多存储库来进行模拟和其他操作。

所以我猜我应该将它们分组。但是我不确定如何对它们进行分组。

现在我创建了一个注册存储库来处理我所有的注册内容。但是,在我有 3 个存储库来执行此操作之前,我需要更新大约 4 个表。

例如,其中一个表是许可证表。当他们注册时,我查看他们的 key 并检查它是否存在于数据库中。现在,如果我需要在注册以外的其他地方检查此许可证 key 或该表中的其他内容,会发生什么情况?

一个地方可能是登录(检查 key 是否未过期)。

遇到这种情况我该怎么办?再次重写代码(break DRY)?尝试将这两个存储库合并在一起,并希望在其他某个时间点不需要任何方法(比如我可能有一个方法来检查是否使用了 userName - 也许我会在其他地方需要它)。

此外,如果我将它们合并在一起,我要么需要 2 个服务层进入同一个存储库,因为我认为拥有一个站点的 2 个不同部分的所有逻辑会很长,而且我必须有像 ValidateLogin() 这样的名称, ValdiateRegistrationForm()、ValdiateLoginRetrievePassword() 等

或者无论如何调用存储库只是有一个听起来很奇怪的名字?

似乎很难创建一个具有足够通用名称的存储库,以便您可以将它用于应用程序的许多位置并且仍然有意义,而且我认为在存储库中调用另一个存储库不是一个好习惯吗?

最佳答案

我在使用存储库模式时做错了一件事——就像你一样,我认为该表与存储库 1:1 相关。当我们应用领域驱动设计中的一些规则时——存储库分组问题通常会消失。

存储库应符合 Aggregate root而不是 table 。这意味着 - 如果实体不应该单独存在(即 - 如果你有一个参与特定 RegistrationRegistrant) - 它只是一个实体,它不需要存储库,它应该通过它所属的聚合根的存储库更新/创建/检索。

当然 - 在许多情况下,这种减少存储库数量的技术(实际上 - 它更像是一种构建域模型的技术)无法应用,因为每个实体都应该是一个聚合根(高度依赖于您的域,我只能提供盲目猜测)。在您的示例中 - License 似乎是一个聚合根,因为您需要能够在没有 Registration 实体上下文的情况下检查它们。

但这并不限制我们级联存储库(Registration 存储库可以在需要时引用 License 存储库)。这并不限制我们直接从 Registration 对象引用 License 存储库(最好 - 通过 IoC)。

只是尽量不要通过技术带来的复杂性或误解来插入您的设计。仅仅因为您不想构建 2 个存储库而在 ServiceX 中对存储库进行分组并不是一个好主意。

更好的方法是给它一个合适的名称 - RegistrationService

但一般应避免使用服务 - 它们通常是导致 anemic domain model 的原因.

编辑:
开始使用 IoC。它真正减轻了注入(inject)依赖项的痛苦。
而不是写:

var registrationService = new RegistrationService(new RegistrationRepository(),  
      new LicenseRepository(), new GodOnlyKnowsWhatElseThatServiceNeeds());

你将能够写:

var registrationService = IoC.Resolve<IRegistrationService>();

附言最好使用所谓的 common service locator但这只是一个例子。

关于c# - 如何正确使用仓库模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1495553/

相关文章:

c# - 在什么情况下,C#中的赋值不能更改变量的值?

c# - NHibernate MySQL 枚举

asp.net - HTML 文本输入撤消不起作用

asp.net - 我如何让中继器的Itemcommand事件不执行整页回发?

c# - 如何为不同的构建配置使用不同的应用程序设置?

c# - 在操作结果中将 EditorTemplate 作为 PartialView 返回

c# - 导致 UI 卡住或变慢的操作事件

.net - Microsoft.Speech 通用语言语法

asp.net - 在 ASP.net 中返回纯文本或其他任意文件

c# - 防止重入并确保为某些操作获取锁的正确方法是什么?