关于域对象、服务层以及使用 Linq2SQL 和 ASP.net MVC 与存储库模式的问题

发布于 2024-10-10 13:05:29 字数 1223 浏览 3 评论 0原文

首先,对下面对我的大脑空间的冗长描述表示歉意。我仍然在思考许多这些新想法,所以我确信我描述的有些东西是错误的。请随时纠正我的错误之处。

我们正处于新 ASP.net MVC2 站点的研发阶段,希望确保我们能够 1) 将数据存储与应用程序分离,2) 允许通过单元测试来测试我们的应用程序,3) 允许我们更改我们的数据存储或使用 Linq2SQL 以外的其他东西。

这个看似简单的目标为我打开了一个全新的世界,其中包括存储库模式、IoC、DI 以及各种其他让我头晕的东西。以下是迄今为止所关注的内容,或者至少是我认为实现我们目标的一个有点正确的计划:

  1. 我们将拥有许多ISpecificRepository接口,它们定义了用户之间的合同接口和底层数据存储。

  2. SpecificRepository 实现将查询特定数据存储并返回代表我们的域对象(或其集合)的 POCO。

  3. 服务层将使用传递给各种服务方法的 ISpecificRepository 实例来执行应用程序特定的业务逻辑,并将这些 POCO 域对象传递回我们的表示层。

如前所述,我们计划使用 Linq2SQL 来实现应用程序的特定存储库,并决定通过为域对象创建 POCO 并创建这些对象与 LINQ 生成的实体之间的映射,将服务层与此实现解耦。 。然后,在服务层中,我们可以创建业务逻辑来查询存储库、添加数据以及为每个用例执行我们需要执行的任何其他操作。这看起来不错,但我担心的是,由于我们使用的是 Linq2SQL,我们的特定 Linq 存储库实现现在必须容纳服务层有效实现业务逻辑所需的所有 Get 查询。

我很好奇这是否会以某种方式破坏存储库模式,因为我们现在不在服务层中而是在存储库中存储应用程序特定的逻辑。

我觉得我们需要这样做的原因是,我可以使用各种 DataLoadOptions 等在我的特定 Linq 存储库上编写更高效的 Linq 查询,而无需从我的存储库返回 IQueryable 到我的服务层,在服务层中,这似乎是某种逻辑实际上属于。另外,我见过的所有示例 IRepository 接口看起来都非常轻量级,只提供了一些对底层数据存储的 GetByID、GetAll、Find、Insert、Delete 和 SubmitChanges 方法。就我而言,听起来我的特定存储库要做的事情远不止于此。

感谢您阅读本文。任何可以澄清我的误解的帮助将不胜感激。

-穆斯塔法

First off, apologies for the long description of my brainspace below. I'm still wrapping my head around lots of these new ideas, so I'm sure I'm describing something incorrectly. Please feel free to correct me where I'm wrong.

We are in the R&D phase of a new ASP.net MVC2 site and want to ensure that we can 1) decouple our data store from our application, 2) allow for our application to be tested via unit tests and 3) allow us to change out our datastore or use something other than Linq2SQL down the line.

This seemingly simple goal has opened up a whole new world to me that includes the Repository pattern, IoC, DI, and all sorts of other things that are making my head swim. Here's what is so far coming into focus, or at least what I believe is a somewhat correct plan to reach our goals:

  1. We will have a number of ISpecificRepository interfaces that define the contract between users of the interface and the underlying data store.

  2. The SpecificRepository implementations will query specific datastores and return POCO representing our domain objects (or collections of them).

  3. Our Service Layer will perform the application specific business logic using an instance of ISpecificRepository passed to the various service methods and pass these POCO domain objects back to our presentation layer.

As mentioned, we are planning on using Linq2SQL to implement our specific repositories for the application and have decided to decouple our service layer from this implementation by creating the POCO for our domain objects and create a mapping to and from these objects to the LINQ generated entities. In the service layer, we can then create business logic to query the repository, add data, and do whatever else we need to do for each use case. This seems fine but my concern is that since we're using Linq2SQL, our specific Linq repository implementation will now have to house all of the many Get queries that the service layer requires to implement the business logic efficiently.

I'm curious as to whether this somehow breaks the Repository pattern since we're now housing application specific logic not in the service layer but in the repository instead.

The reason I feel that we need to do it this way is so that I can write more efficient Linq queries on my specific Linq repository using various DataLoadOptions, etc. without returning IQueryable from my repository up to my service layer, where it would seem that sort of logic actually belongs. Also, all of the example IRepository interfaces I've seen seem very lightweight and only provide a few methods to GetByID, GetAll, Find, Insert, Delete, and SubmitChanges to the underlying data store. In my case, it sounds like my specific repositories will be doing a great deal more than that.

Thanks for reading this far. Any and all help that can clarify my misconceptions would be greatly appreciated.

-Mustafa

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

生寂 2024-10-17 13:05:29

我们特定的 Linq 存储库
实施现在必须安置
所有的许多 Get 查询
服务层需要实现
有效地处理业务逻辑。

我很好奇这是否以某种方式
打破存储库模式

完全 。存储库是域实体的集合。如果我有一个 AccountsRepository,那么需要 Accounts.ThatAreOverdue() 是完全合理的。

我个人更喜欢流畅的命名。 Accounts.ThatAreOverdue() 感觉比 AccountRepository.GetOverdue() 更好..但我认为这是一个偏好点。

此外,所有示例 IRepository
我见过的界面看起来很
轻量级且仅提供少量
GetByID、GetAll、Find 的方法,
插入、删除和提交更改
底层数据存储。

存储库接口可以很薄。 Find 旨在与规范模式一起使用。将条件封装在另一个对象中。标准的实现可以传递要查询的 Linq2Sql 对象 - 但针对内存中域对象重用标准类会更加困难(与涉及 Linq2Sql 的数据库相比)。

我们的服务层将执行
应用程序特定的业务逻辑
使用一个实例
ISpecificRepository 传递给
各种服务方法并通过这些
POCO域对象回到我们的
表示层。

您是说您的逻辑将全部位于服务中,并且“域对象”将是属性包并绑定到视图中?

我不认为我会推荐这样做。

如果应用程序逻辑中使用的同一对象也在视图中使用,那么您就紧密耦合了两个应用程序层,并且经验表明这会导致问题。如果视图使用相同的对象,那么通过更改来保持服务和域的一致性将非常困难。视图将需要数据片段,并且它们将不可避免地卡在不属于域中的位置。

our specific Linq repository
implementation will now have to house
all of the many Get queries that the
service layer requires to implement
the business logic efficiently.

I'm curious as to whether this somehow
breaks the Repository pattern

Not at all. A Repository is a collection of domain entities. If I have a Repository of Accounts, it is perfectly reasonable to want Accounts.ThatAreOverdue().

I personally prefer fluent naming. Accounts.ThatAreOverdue() feels better than AccountRepository.GetOverdue() .. but I suppose that is a point of preference.

Also, all of the example IRepository
interfaces I've seen seem very
lightweight and only provide a few
methods to GetByID, GetAll, Find,
Insert, Delete, and SubmitChanges to
the underlying data store.

A Repository interface can be thin. Find is meant to be used with the Specification pattern. Encapsulate the criteria in another object. The implementation of the criteria can be passed Linq2Sql objects from which to query - but it will be more difficult to re-use the criteria classes against in-memory domain objects (versus in database, where Linq2Sql is involved).

Our Service Layer will perform the
application specific business logic
using an instance of
ISpecificRepository passed to the
various service methods and pass these
POCO domain objects back to our
presentation layer.

Are you saying that your logic will all be in Services and the "domain objects" will be bags of properties and bound to in the view?

I don't think I'd recommend that.

If the same object that is used in the application logic is also used in the view, then you have tightly coupled the two application layers and experience says that causes problems. It will be very difficult to maintain coherence in the Services and Domain through changes if the View uses the same objects. The View will need pieces of data and they will inevitably get stuck onto places they don't really belong in the domain.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文