ASP.NET MVC - 是否可以使用副业表示逻辑?

时间:2011-05-17 13:11:25

标签: asp.net-mvc

在大多数关于ASP.NET MVC的文档中,整个“关注点分离”都被大量推动。依赖注入/控制反转,单元测试,保持视图之外的“逻辑”等。

但这有多远意图推动?如果特定任务需要超出View / Model / Persistence“三层”方法的额外逻辑,这是不好的做法吗?

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

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视图需要一些非常抽象的逻辑,因此我需要参与Models并安排一个持久存储在数据库中的View Model

这在我的Data部分中不会发生,因为这会释放它的可重用性,并且流程中包含业务逻辑。它不能完全发生在我的Models部分,因为这需要它知道Data部分,而不是Web部分。我不想把它放在Project.Presentation部分,因为我不想要那里的数据访问代码。

问题

对我来说,添加引用Data.dllModels.dll以构建我需要的{{1}}项目是否会严重违规?此外,除了项目问题之外,这一般是一种糟糕的方法,还是这种情况很多你有时会发现自己不得不这么做?我的一部分感觉如果我不得不诉诸于此,那么我只是错误地构建了我的软件 - 但同时我非常有信心我做了一个相当不错的工作,制作一个原始的太抽象了没有中间人安排的HTML解释。

4 个答案:

答案 0 :(得分:2)

我使用以下结构,这或多或少地解决了我们在MVC结构方面遇到的所有问题。

  • 模型:包含所有ViewModel。干净,只有吸气剂和制定者。
  • 业务逻辑实现:包含数据库逻辑,DAL实体等的项目集。但只有一个接口(在我们的例子中,这是一个WCF API)。
  • ServiceLayer:Business Logic和ViewModels之间的桥梁。对网络一无所知。
  • 映射层:业务实体与ViewModel之间的转换。
  • Web项目:拥有非常精简的控制器和视图,以及与Web相关的所有内容。

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

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

在代码中,这看起来像:

// 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转换为提供给业务逻辑的数据实体。

答案 1 :(得分:2)

根据我的经验,单一责任是编写您希望尽早及经常更改的代码的好方法。和Jan一样,我在谁做什么的时候也有一条线。您执行此操作的次数越多,就越容易替换系统的一部分。我最近使用EF4.1删除了linq2sql,并且由于SRP,一旦我通过我的新EF4层进行测试,其他一切都正常工作。

那就是说,我通常让单元测试决定这些东西的存在 - 这是我的SRP驱动程序,并且询问基本问题“必须=类/服务=知道=其他东西=做它的工作吗?”如果答案是否定的,那么它会转移到其他地方 - 如果是,那就是依赖性。现在,如果它变得痛苦,那就是它告诉我“这是愚蠢的”(see this question for the stupid)的方式,我试图强迫某些东西,而不是让它符合它必须的方式。

在您的核心问题上:您已清楚地发现代码中存在差距 - 它必须知道两件事(数据和模型)并且我同意,它应该是它自己的东西并被拉出来。我将其称为“DomainService”或者可能只是DTO,但演示文稿感觉它不仅仅是准备数据。 (我认为视图会处理演示文稿......也许你会说服主持人?)。我也反对你认为你做错了“ - 不,你正在学习以不同的方式编写代码并允许它发展,完全应该如此。 : - )

答案 2 :(得分:1)

“参与模型并安排一个持久存储在数据库中的视图模型”

然后它不是一个视图模型。

这会简化事情吗?

答案 3 :(得分:0)

什么是'ViewModel':

“ViewModel”常常与持久性混淆。如果你仔细看一下这个词,它就是'View'+'Model'的组合 - 这实际上意味着它是满足你视图所有需求所需的单个数据单元。 ViewModel可以推断出多个实体或源来构建View所需的内容。

现在来看你的问题:

对我来说,添加一个引用Data.dll和Models.dll来构建我需要的Project.Presentation项目是否存在严重违规行为?

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

只需2美分!