如何在我的MVC项目之外重构我的数据库访问代码,但保留我的viewmodel?

leo*_*ora 19 c# model-view-controller asp.net-mvc refactoring asp.net-mvc-viewmodel

我有一个asp.net-mvc网站,其中包含以下文件夹:

  • 控制器
  • 脚本
  • 查看
  • 的ViewModels
  • 楷模
  • 的DomainModel

我现在想要在另一个.net应用程序(一个Windows控制台应用程序,所以根本不是网络)访问大量的业务逻辑和数据库访问代码和数据,所以我重构尽可能多的东西移除MVC项目和进入解决方案中的其他项目,以便可以与其他解决方案共享代码.

我有两个主要问题;

  1. 我的主要问题是我正在努力找到一个放置生成ViewModel的代码的地方,因为我想在我的控制台应用程序中重用这些代码,因为控制台应用程序发送的电子邮件需要相同的数据.视图.

  2. 另一个主要问题是,当我的许多实例化我的视图模型的函数以一堆数据库访问代码开始时,我仍然很难看到如何将我的数据库访问代码移出MVC项目,同时仍然有ViewModel.

到目前为止,这里有一些细节和我的过程:

第1步 - 将DomainModel移动到另一个项目 - 成功

所以移动DomainModel项目很简单(因为那里有许多原始对象,其中包含一些业务逻辑 - 没有关于它的网络).

第2步 - 细化控制器 - 成功

我尽可能地减少了控制器的数量,并将任何业务逻辑或复杂的数据访问逻辑移到了Models文件夹中.当我试图将模型文件夹移到MVC项目之外时,有些事情破了:

第3步 - 尝试在MVC项目之外移动Models文件夹 - 努力

在稀疏控制器时,我有许多不同的控制器动作可以转到模型类并返回我传递回视图的ViewModel.像这样的东西(在我的控制器类中):

 public ActionResult ApplicationDetail(int id)
 {
      AppDetailViewModel applicationViewModel = Model.GenerateAppDetailViewModel(id);
      return View(applicationViewModel);
 }
Run Code Online (Sandbox Code Playgroud)

所以我的Model文件夹中的文件依赖于ViewModel类.我确实希望集中GenerateAppDetailViewModel()函数,因为它在多个不同的控制器中使用.此外,在我的控制台应用程序(发送电子邮件,我经常想要获取恰好在某个视图上的所有数据,所以我的代码"希望"也利用视图模型..如果我将它移出MVC项目然后我可以重用但我认为有依赖性问题(显然我不需要在我的控制台应用程序中使用SelectListItem,但在其他情况下,它们只是生成视图所需的不同数据的容器对象,我确实要重用)

或另一件破坏的事情是依赖:

System.Web.Mvc
Run Code Online (Sandbox Code Playgroud)

因为我有很多代码:

  1. 查询数据库中的表
  2. 将其转换为对象集合(我正在使用nhibernate)
  3. 将其转换为某个DTO对象(位于ViewModels文件夹中)或SelectListItem对象列表(用于填充视图中的下拉列表),它是System.web.mvc的一部分.

我想寻找关于打破这种依赖关系的最佳方法的建议,这样我就可以尽可能多地从MVC项目中移出代码以便重用.

问题是,如果我尝试将我的ViewModel代码吸入Model文件夹并进入另一个项目,那么我再次陷入困境,因为ViewModel类有很多依赖性

System.Web.Mvc

由于像SelectListItem这样的东西.

我应该有2个视图模型文件夹(MVC项目中有一个具有特定的system.web.mvc引用,另一个位于不同的项目中吗?).似乎依赖于SelectListItem是导致争用的原因

在我看过的大多数示例中,ViewModes确实依赖于System.Web.Mvc,例如本教程

我看过这些问题:

哪些是相关的,但不确定他们回答我所说的具体的整体重构问题.

Dar*_*rov 17

视图模型特定于特定应用程序.我想您的Web应用程序和控制台应用程序之间的视图模型会有所不同.因此,每个应用程序都定义自己的视图模型以及域模型和视图模型之间的相应映射.不要让您的域模型拥有将它们转换为视图模型的方法,因为这样您就可以将域层完全绑定到UI层,这是最糟糕的事情.使用映射层(将特定于每种应用程序类型).AutoMapper是您可以拥有的映射层的一个很好的例子.

甚至不要尝试在控制台应用程序中重用ASP.NET MVC视图模型.正如您已经发现的那样,它们将包含对System.Web.Mvc的引用,因为例如ASP.NET MVC中的dropDownList用IEnumerable<SelectListItem>类表示,而在控制台应用程序中,上帝知道,也许是IEnumerable<SomeItemViewModel>.

结论:在域和视图模型之间查看模型和来回映射属于UI层(即ASP.NET MVC,Console,WPF,...).