假设我有这样的表:
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 保留在表示端,而域模型保留在存储库端,那么我会选择逻辑层。
网络层:
- View :接收 View 模型
- Controller :与 Viewmodel 和 WebLogic 配合使用
- WebLogic:与 Viewmodel、Service 和 Domain 模型配合使用
应用层:
- 服务:适用于域模型,
- 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/