c# - N 层架构 C# mvc ViewModels

标签 c# asp.net-mvc n-tier-architecture asp.net-mvc-viewmodel

假设我有这样的表:

Users
------
UserId
Email
...

People
------
PersonId
UserId
Name
Country
...

对应型号:

public class User{
   ...
}

public class Person{
   ...
}

我希望在我的 MVC 应用程序中显示所有人的 View ,包括他们的电子邮件地址。

我的解决方案是在不同的项目中构建的,例如:

Comp.App.Services
Comp.App.Dal
Comp.App.Web

理想情况下,我在 Controller 中创建一个 View 模型,以便稍后填充我的 View ,如下所示:

public class PersonListItemViewModel{
    public string Name { get; set; }
    public string Country { get; set; }
    public string Email { get; set; }
}

现在问题来了。我想在我的服务层中通过 1 个查询获取数据,但服务层必须不知道 View 模型,并且查询不应返回任何额外的字段。仅我在 View 模型中指定的字段。

我红色了许多 N 层应用程序的最佳实践,但我似乎无法弄清楚如何在不让我的服务层了解 View 模型的情况下实现这一点。这似乎不正确。我总是假设我的服务层只能了解域模型,但在现实世界的应用程序中,我总是遇到这样的问题:我想将查询限制为例如仅 2 个字段。如果我的服务仅讨论域模型,则无法完成此操作。

我是否误解了这种方法?

PS。我在我的 Dal 项目中使用 Dapper。

编辑: 它不是 Converting DTOs to View Models 的重复项 。我知道自动映射器。让我问一个稍微不同的问题。当我有一个名为 GetPeopleWithEmail() 的方法时,我的服务应该返回什么???

根据我现在在 anwsers 中阅读的内容,它应该返回一个 DTO,并将 DTO 转换为我的 Controller 中的 ViewModel。对吗?

最佳答案

如果您希望确保 ViewModel 保留在表示端,而域模型保留在存储库端,那么我会选择逻辑层。

  1. 网络层:

    • View :接收 View 模型
    • Controller :与 Viewmodel 和 WebLogic 配合使用
    • WebLogic:与 Viewmodel、Service 和 Domain 模型配合使用
  2. 应用层:

    • 服务:适用于域模型,
    • BusinessLogic:使用存储库和域模型
    • 存储库:与数据存储配合使用

我强烈建议使用一些依赖注入(inject),例如 Unity帮助管理依赖关系。

例如,在我上面的结构中,SomeController 将接受 SomeWebLogic,SomeWebLogic 将接受 ISomeService。 SomeWebLogic 会调用 ISomeService 将 SomeDomainModel 转换为 SomeViewModel,最终由 SomeController 使用。

在应用层方面,SomeService 将接收 SomeBusinessLogic,后者将接收 ISomeRepository。

在您的示例中 - 使用我建议的结构:

--Web层--

PersonView.cshtml:

@model List<PersonListItemViewModel>;

@foreach(var person in model)
{
   //some html binding
}

PersonController.cs:

public ActionResult PersonView()
{
   var personWebLogic = new PersonWebLogic(); //would suggest DI instead
   var personsModelList = personWebLogic.GetPersons();
   return View(personsModelList );
}

PersonWebLogic.cs

public List<PersonListItemViewModel> GetPersons()
{
   var personService = new PersonService(); //suggest DI here again
   var people = personService.GetPeople(); //returns a list of domain models
   var personsViewModelList = new List<PersonListItemViewModel>();
   foreach(var person in people)
   {
     //use some custom function to convert PersonDomainModel to PersonListItemViewModel
     personalsViewModel.Add(MapPersonDomainToPersonView(person)); 
   }
   return personsViewModelList;
}

--应用层--

人员服务

public List<Person> GetPeople()
{
   var personLogic = new PersonLogic(); //use DI for this
   return personLogic.GetPeople(); //return type will be dependent on your service architecture
}

个人逻辑

public List<Person> GetPeople()
{
   var personRepostitory = new PersonRepository(); //DI...
   var personDataTable = personRepository.GetAllPeople(); //return type will vary on your repository structure
   //Custom function to map to person list from data table, this could be in repo, all depends on your desired structure
   return MapPersonDataTableToPersonList(personDataTable);
}

人员存储库

public DataTable GetAllPeople()
{
   var database = GetDatabase();
   var dataTable = ...//call db to get person datatable
   return dataTable;
}

关于c# - N 层架构 C# mvc ViewModels,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30328573/

相关文章:

javascript - asp.net mvc - 如何使用 Javascript 创建多个 DropDownList

asp.net-mvc - Razor View 引擎 : Complex looping and HTML

c# - C#中的命名空间冲突

c# - 如何在 .NET 核心中使用 .settings 文件?

jquery - 验证动态添加的控件

architecture - n 层系统是否为大型数据集处理生成 "sense"?

c# - 设计提示,薪资系统...重新发布

java - N 层发布/订阅者设计问题

c# - 如何使用 IEnumerable 实现进度?

c# - WPF如何启动App.xaml/cs和MainWindow.xaml/cs