MVC 存储库模式设计决策 [英] MVC repository pattern design decision

查看:25
本文介绍了MVC 存储库模式设计决策的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 asp .net MVC 应用程序,最近开始使用服务验证层实现存储库模式,很像 这个.

I have an asp .net MVC application and recently started implementing the repository pattern with a service validation layer, much like this.

我一直在为我创建的每个模型创建一个存储库/服务.这是矫枉过正吗?相反,我是否应该为每个为许多不同模型提供 CRUD 的逻辑业务领域创建一个存储库/服务?

I've been creating one repository/service for each model that I create. Is this overkill? Instead, should I create one repository/service for each logical business area that provides CRUD for many different models?

对我来说,似乎我要么用许多文件把项目树弄得乱七八糟,要么用许多方法把一个类弄得乱七八糟.6 一个方式半打另一个.你能想出任何好的论据吗?

To me, it seems like I'm either cluttering the project tree with many files or cluttering a class with many methods. 6 one way half dozen the other. Can you think of any good arguments either way?

推荐答案

一般来说,如果您使用的是真正的"存储库模式,而不是其他持久层(例如 ActiveRecord 或 DAO),您应该致力于识别您的域聚合,并为每个聚合创建一个存储库.

Generally, if you're using a "true" Repository Pattern, as opposed to other persistence layers (e.g. ActiveRecord or DAO's), you should aim to identify your domain aggregates, and create one repository per aggregate.

这是什么意思?嗯,这在很大程度上取决于您的应用,但通常有些对象自然是其他对象的父级",或者是相关事务的一部分.

What does that mean? Well, it depends a lot on your app, but generally there are objects which are naturally 'parents' of other objects, or which are part of a related transaction.

我认为典型的例子是一个电子商务系统,其中您有一个订单的概念,在一个订单中,您有订单行,每个订单行是一些产品和数量,等等.

I think the canonical example is an ecommerce system in which you have a concept of an order, and in an order you have orderlines each orderline is some product and a quantity, and so on.

在这种情况下,Order 对象是系统的聚合根之一,并且会创建一个 OrderRepository.

In that case, the Order object is one of the system's aggregate roots and an OrderRepository is created.

在这种情况下要记住的是,订单与其订单线等之间存在某种关系(暗示的或其他的).因此,Repository 上CRUD"的 C-UD 部分通常应该只是一种方法,并且通常应该只接收该聚合根对象的一个​​实例并对其进行操作(例如 repo.Save(order)).其他可能的参数可能存在,但这取决于您的实现.

The thing to remember in that case is that there's some relationship (implied or otherwise) between a order and its orderlines and so on. So the C-UD parts of "CRUD" on the Repository should generally just be one method each, and should generally just take in an instance of that aggregate root object and operate on it (.e.g. repo.Save(order)). Other possible params might be there, but that depends on your impl.

事实上,您通常可以通过继承来解决大部分 C-UD 部分(即使用一些关于您的特定持久性方案应该发生什么的已知逻辑来创建一个 RepositoryBase 来实现它们).

IN fact, you can often solve most of the C-UD part w/ inheritance (i.e. make a RepositoryBase that implements them using some known logic about what shoudl happen for your particular persistence scheme).

这样我们就剩下了 CRUD 的 R 部分.在这种情况下,如果您选择使用查询方法路线,您可能会获得大量查询方法(GetById;GetByName;GetByCustomerName 等).有些人更喜欢,特别是对于简单的应用程序,公开基于 linq 的接口(例如 IQueryable GetAll()),然后可以应用 Where 子句.YMMV 取决于您对那个的潜在持久性,但对于简单的应用程序来说,这是一个可靠的镜头,尤其是.如果您希望持久性提供程序直接支持 linq.

So that leaves us the R part of CRUD. In this case is where you might get a ton of query methods (GetById; GetByName; GetByCustomerName, etc) if you choose to go the query method route. Some folks prefer, espeically for simple apps, exposing a linq-based interface (e.g. an IQueryable GetAll()) that can then have Where clauses applied. YMMV depending on your underlying persistence on that one, but it's a solid shot for simple apps, esp. if you expect your persistence provider to support linq directly.

最后,许多人实际上通过一种或另一种命令查询职责分离模式将查询部分分离出来,这表明用于持久化和查询的接口应该不同.在这种情况下,您将拥有一个仅包含基本 CRUD(GetById、GetAll、Save、Delete)操作的 Repo 和另一种基于应用意图查询事物的类.

Lastly, many folks actually separate out the query part via one implentation or another of the Command Query Responsibility Separation pattern, which says the interfaces for persisting and querying should be different. IN that case, you'd have a Repo that just has basic CRUD (GetById, GetAll, Save, Delete) ops and another class of some sort which queries things based on your app's intentions.

希望有所帮助.

保罗

这篇关于MVC 存储库模式设计决策的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆