ASP.NET MVC - 可以有副业表示逻辑吗?

发布于 2024-11-07 18:10:40 字数 924 浏览 0 评论 0原文

在您读到的有关 ASP.NET MVC 的大多数文档中,都大力提倡整个“关注点分离”。依赖注入/控制反转、单元测试、将“逻辑”排除在视图之外等等。

但是这要推到什么程度呢?如果特定任务需要视图/模型/持久性“三层”方法之外的额外逻辑,这是不好的做法吗?

例如,我有一个包含四个单独项目的解决方案。

Project.Web (ASP.NET MVC) [ References Data.dll, Models.dll ]
Project.Data (Fluent nHibernate Mapping) [ References Models.dll ]
Project.Models (POCO, Helpers, Factories, etc)
Project.Tests (Unit Testing)

到目前为止,这对我来说非常有用。但我的一些 MVC 视图需要一些非常抽象的逻辑,这样我就需要参与模型并安排一个保存在数据库中的视图模型。

这不会发生在我的 Data 部分中,因为这会影响它的可重用性,并且该流程中包含业务逻辑。它不可能完全发生在我的 Models 部分中,因为这需要它了解 Data 部分,但它并不这样做。我不想将其放在 Web 部分中,因为我不希望那里有数据访问代码。

问题

我添加一个引用 Data.dllModels.dll 来构建的 Project.Presentation 项目是否存在严重违规我需要什么?此外,除了项目问题之外,这总体上是一种不好的方法还是很多人发现自己有时不得不这样做?我的一部分感觉,如果我不得不诉诸于此,那么我只是构建了错误的软件 - 但同时我非常有信心我已经完成了相当好的工作,它太抽象了,无法制作原始的HTML 解释无需中间人安排。

In most documentation you read about ASP.NET MVC, the entire 'Separation of Concerns' is very heavily pushed. Dependency Injection/Inversion of Control, Unit Testing, keeping 'logic' out of the Views, etc.

But how far is this intended to be pushed? Is it bad practice if a specific task requires extra logic beyond the 'three layer' approach of View/Model/Persistence?

For example, I have a solution set up with four individual projects.

Project.Web (ASP.NET MVC) [ References Data.dll, Models.dll ]
Project.Data (Fluent nHibernate Mapping) [ References Models.dll ]
Project.Models (POCO, Helpers, Factories, etc)
Project.Tests (Unit Testing)

Up until now, this has served me pretty well. But I require some very abstract logic for some of my MVC Views, such that I need to take part of the Models and arrange a View Model that is persisted in the database.

This cannot happen in my Data section, as that would dispose the re-usability of it, and there is business logic included in the process. It cannot entirely happen in my Models section, because that would require it to have knowledge of the Data section, which it does not. And I do not want to put it in the Web section because I don't want data access code there.

Question

Is it in massive violation for me to add, say, a Project.Presentation project that references Data.dll and Models.dll to construct what I need to? Moreover project concerns aside, is this a bad approach in general or is this something a lot of you find yourselves having to do at times? Part of me feels that if I am having to resort to this, then I've just built my software wrong - but at the same time I am very confident I have done a fairly good job, it is just too abstract to make a raw HTML interpretation of without middle-man arrangement.

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

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

发布评论

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

评论(4

夏天碎花小短裙 2024-11-14 18:10:40

根据我的经验,单一责任是编写希望尽早且经常更改的代码的好方法。和简一样,我在谁做什么、何时做什么之间也有明确的界限。您执行得越多,替换系统的一部分就越容易。我最近用 EF4.1 删除了 linq2sql,并且由于 SRP,一旦我的新 EF4 层通过了测试,其他一切就正常了。

也就是说,我通常让单元测试决定这些东西所在的位置——这是我的 SRP 的驱动程序,并提出基本问题“必须=类/服务=了解=其他东西=才能完成它的工作?”如果答案是否定的,它就会去其他地方——如果是,那就是依赖。现在,如果它变得痛苦,那就是它告诉我“这很愚蠢”的方式(为愚蠢的人看这个问题),我试图强迫一些东西,而不是让它适应它必须的方式。

关于你的核心问题:你已经清楚地发现了代码中的一个缺口——它必须知道两件事(数据和模型),我同意,它应该是它自己的东西并退出。我将其称为“DomainService”或者只是 DTO,但演示感觉它不仅仅只是准备数据。 (我认为视图处理演示文稿......也许您只是指演示者?)。我也反对你认为你做“错事”的看法 - 不,你正在学习以不同的方式编写代码并允许它发展,完全正如它应该的那样。 :-)

It's been my experience that single responsibility is a great way to write code you expect to change early and often. Like Jan, I too have a solid line between who does what, when. The more you enforce this, the easier it is to replace an slice of your system. I recently removed linq2sql with EF4.1 and because of SRP, once I got the tests passing around my new EF4 layer, everything else just worked.

That said, I typically let unit testing dictate where these things live -- it's my driver for SRP as well as asking the basic question "must =class/service= know about =something else= to do it's job?" If the answer is no, it goes somewhere else -- if yes, it's a dependency. Now, if it becomes painful, that's its way of telling me "this is stupid" (see this question for the stupid) and I've attempted to force something instead of allowing it to fit the way it must.

Onto your core queston : you've clearly identified a gap in your code -- it MUST know about two things (data and model) and I agree, it should be its own thing and pulled out. I would call this a "DomainService" or maybe just DTO, but presentation feels like it would be doing more than just prepping data. (I'd argue the view handles the presentation ... maybe you simlpy mean presenter?). I would also argue against your perception that you did "something wrong" - no, you're learning to write code differently and allowing it to evolving, EXACTLY as it should. :-)

〆一缕阳光ご 2024-11-14 18:10:40

我使用以下结构,它或多或少解决了我们遇到的有关 MVC 结构的所有问题。

  • Models:包含所有 ViewModel。只是干净,只有 getter 和 setter。
  • 业务逻辑实现:包含数据库逻辑、DAL 实体等的一组项目。但只有一个接口(在我们的例子中,这是一个 WCF API)。
  • ServiceLayer:业务逻辑和ViewModel 之间的桥梁。对网络一无所知。
  • 映射层:业务实体和ViewModel之间的转换。
  • Web 项目:包含非常薄的控制器和视图,以及与 Web 相关的所有内容。

网页流程将遵循以下流程:

  • URL 映射到某个 Action
  • 动作非常干净,它们仅引用 ServiceLayer 中的方法
  • ServiceLayer 在业务逻辑实现中执行一个或多个操作(获取数据、存储数据等)
  • 服务层将业务实体传递到映射层。
  • 映射层将业务实体转换为 ViewModel

在代码中,这看起来像:

// action
public ActionResult ListOfObjects () {
    var model = new ServiceLayer.ObjectsClient().GetListOfObjects();
    return View(model);
}

// Service Layer
public ListOfObjectsModel GetListOfObjects () {
    var businessEntities = BusinessDao.GetThingysFromDb();

    var model = Mapper.TranslateToViewModel(businessEntities);

    return model;
}

// Mapping Layer
public ListOfObjectsModel TranslateToViewModel(List<BusinessEntity> entities) {
    // do mapping
}

处理 POST 时,您将遵循相同的流程,但映射层应将您的 ViewModel 转换为提供给业务逻辑的数据实体。

I use the following structure, which more or less solves all problems we've had regarding MVC structures.

  • Models: contains all ViewModels. Just clean, only getters and setters.
  • Business logic implementation: Set of projects that contains database logic, DAL entities etc. But only has one interface (in our case this is a WCF API).
  • ServiceLayer: the bridge between Business Logic and ViewModels. Doesn't know anything about web.
  • Mapping layer: translation between business entities and ViewModels.
  • Web project: holds very thin Controllers and Views, and everything web related.

A web page flow will follow this flow:

  • URL maps to a certain Action
  • Actions are really clean, they only reference a method in the ServiceLayer
  • The ServiceLayer executes one or more actions in the Business Logic Implementation (get data, store data, etc.)
  • The ServiceLayer passes the business entities to the Mapping Layer.
  • The Mapping Layer translates business entities into ViewModels

In code this would look like:

// action
public ActionResult ListOfObjects () {
    var model = new ServiceLayer.ObjectsClient().GetListOfObjects();
    return View(model);
}

// Service Layer
public ListOfObjectsModel GetListOfObjects () {
    var businessEntities = BusinessDao.GetThingysFromDb();

    var model = Mapper.TranslateToViewModel(businessEntities);

    return model;
}

// Mapping Layer
public ListOfObjectsModel TranslateToViewModel(List<BusinessEntity> entities) {
    // do mapping
}

When handling POSTs you will follow the same flow, but the mapping layer should translate your ViewModel into Data Entities that are given to the Business Logic.

雪若未夕 2024-11-14 18:10:40

“获取模型的一部分并安排一个持久存在数据库中的视图模型”

那么它就不是视图模型。

这会让事情变得简单吗?

"take part of the Models and arrange a View Model that is persisted in the database"

Then its not a viewmodel.

Does that simplify things?

还如梦归 2024-11-14 18:10:40

什么是“ViewModel”:

“ViewModel”经常与持久性混淆。如果您更仔细地观察这个词,它是“视图”+“模型”的组合 - 这本质上意味着它是满足视图的所有需求所需的单个数据单元。 ViewModel 可以推断多个实体或源来构建视图所需的内容。

现在回答你的问题:

我添加引用 Data.dll 和 Models.dll 来构建我需要的内容的 Project.Presentation 项目是否严重违规?

回复:如果我必须这样做,我会在我的 MVC 项目中创建一个名为“ViewModels”的单独命名空间(文件夹),并将所有 Viewmodel 放在其中。在我看来,如果您希望 ViewModel 位于单独的命名空间中,它实际上不会违反 MVC。您只是增加了间隔或使其更加适合单元测试。

只是我的2分钱!!!

What is a 'ViewModel':

More than often 'ViewModel' is confused with persistence. If you look at the word more closely it is a combination of 'View' + 'Model' - which essentially means it is a single unit of data that is required to fulfill all the needs of your view. A ViewModel can infer multiple entities or sources to build what is required by the View.

Now Coming to your question:

Is it in massive violation for me to add, say, a Project.Presentation project that references Data.dll and Models.dll to construct what I need to?

Re: If I had to do it, I would have created a seperate namespace (folder) in my MVC project named 'ViewModels' and placed all my Viewmodels in there. In my opinion if you want your ViewModels to be in a separate namespace, it would not actually violate MVC. You are just incresing the separation or making it more unit test friendly.

Just my 2 cents!!!

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