我有一个asp .net MVC应用程序,最近开始使用服务验证层实现存储库模式,就像this一样。
我一直在为我创建的每个模型创建一个存储库/服务。这有点矫枉过正吗?相反,我应该为每个为许多不同模型提供CRUD的逻辑业务区域创建一个存储库/服务吗?
对我而言,似乎我要么用多个文件混乱项目树,要么用很多方法弄乱一个类。 6单程半打另一半。你能想到任何好的论据吗?
答案 0 :(得分:16)
通常,如果您使用“真正的”存储库模式,而不是其他持久层(例如ActiveRecord或DAO),则应该确定域聚合,并为每个聚合创建一个存储库。
这是什么意思?嗯,这很大程度上取决于你的应用程序,但通常有一些对象自然是其他对象的“父母”,或者是相关交易的一部分。
我认为规范的例子是一个电子商务系统,你有一个订单的概念,并且在订单中你有订单,每个订单行是一些产品和数量,等等。
在这种情况下,Order对象是系统的聚合根之一,并且创建了OrderRepository。
在这种情况下要记住的是,订单与其订单线之间存在某种关系(暗示或其他),依此类推。因此,存储库中“CRUD”的C-UD部分通常应该只是一个方法,并且通常应该只接受该聚合根对象的实例并对其进行操作(例如,repo.Save(order))。其他可能的参数可能存在,但这取决于你的impl。
事实上,你经常可以解决大部分带有继承的C-UD部分(即创建一个RepositoryBase,使用一些已知的逻辑来实现它们,这些逻辑关于你的特定持久化方案会发生什么)。
这样我们就得到了CRUD的R部分。在这种情况下,如果您选择查询方法路由,可能会获得大量查询方法(GetById; GetByName; GetByCustomerName等)。有些人喜欢(尤其是简单的应用程序)暴露基于linq的界面(例如IQueryable GetAll()),然后可以应用Where子句。 YMMV取决于你对它的潜在持久性,但它对于简单的应用程序来说是一个可靠的镜头,尤其是如果您希望持久性提供程序直接支持linq。
最后,许多人实际上通过命令查询责任分离模式的一个或另一个实现分离出查询部分,该模式表示持久化和查询的接口应该是不同的。在这种情况下,你有一个Repo只有基本的CRUD(GetById,GetAll,Save,Delete)操作和另一类某种类,它根据你的应用程序的意图查询事物。
希望有所帮助。
保
答案 1 :(得分:3)
这是我最近提出的一个问题,尽管得到了几个好的答案,我最终得出了自己的结论 - 没有正确的答案。这并不意味着没有错误的答案,事实上有很多错误的答案,但正确的答案总是取决于你自己的个案。
我最终得到了四个存储库,以及我的EF4实体模型的部分类扩展,用于子实体的标准CRUD操作(地址,电话号码,状态代码等),因此它们实现了一次并可在所有存储库中使用。但是,我仍然在不断改进它,所以也许我还没有遇到最好的解决方案。
我的建议是尝试一下,看看它是否合适,看看它是否合适。通常情况下,如果感觉感觉正确,那么无论如何都是错误的。
如果您真的害怕杂乱的源代码树,您可以随时将模型部分分解为自己的库,并将其作为依赖项包含在内。