我正在重构我工作的项目。我的现有控制器使用了仓储模式,但我仍然进行了一些比我感到舒适的脚手架工作。而且我的一些控制器可能需要传入10个以上的仓储库(通过Ninject)。因此,我决定引入一个服务层,在这里我的意图是每个控制器有一个服务,并且每个服务将注入多个仓储库并完成我需要的工作。迄今为止,这个方法非常有效,但我遇到了一些困惑:如何将模型验证从控制器移到服务层中?例如,看看我OfficesController上的Edit方法:
与控制器的方法相比,它的问题在于我仍然从数据库中获取一个
那么,将验证和模型更新逻辑从控制器移到服务的正确方式是什么?欢迎提出建议!
供参考,这是我的项目结构:
- Data:包含所有模型类 - Data.Google.Maps:包含我需要反序列化特定Kml的所有类 - Data.Models:包含我的DbContext、配置、视图模型和部分视图模型 - Data.Repositories:包含所有与DbContext通信的存储库。由于EF本身就是一个伪存储库,我利用我的“存储库”作为更具体的查询数据的方式。例如:
[HttpPost]
public async Task<RedirectToRouteResult> Edit(
short id,
FormCollection form,
[Bind(Prefix = "Office.Coordinates", Include = "Latitude,Longitude")] Coordinate[] coordinates) {
if (id > 0) {
Office office = await this.OfficesService.GetOfficeAsync(id);
if ((office != null)
&& base.TryUpdateModel(office, "Office", new string[2] {
"Name",
"RegionId"
}, form)
&& base.ModelState.IsValid) {
this.OfficesService.UpdateOfficeAsync(office, coordinates);
}
return base.RedirectToAction("Edit", new {
id = id
});
}
return base.RedirectToAction("Default");
}
与控制器的方法相比,它的问题在于我仍然从数据库中获取一个
Office
对象,进行更新、验证,然后再保存。在这种情况下,复杂性增加而不是减少。之前,我在方法中调用了存储库,现在我调用了服务,该服务调用存储库执行相同的功能。到目前为止,这种复杂性的增加只在我的Edit
方法中表现出来,在其他地方,复杂性大大降低,这正是我想要的。那么,将验证和模型更新逻辑从控制器移到服务的正确方式是什么?欢迎提出建议!
供参考,这是我的项目结构:
- Data:包含所有模型类 - Data.Google.Maps:包含我需要反序列化特定Kml的所有类 - Data.Models:包含我的DbContext、配置、视图模型和部分视图模型 - Data.Repositories:包含所有与DbContext通信的存储库。由于EF本身就是一个伪存储库,我利用我的“存储库”作为更具体的查询数据的方式。例如:
FindTechnicians()
或FindActive()
等。
- Data.Services:包含我将使用的所有服务。服务将注入一个或多个存储库,并执行我需要完成的所有逻辑,然后将一个完整的视图模型返回给控制器。
- Identity:包含我的ASP.NET Identity实现。
- Web.Private:包含实际的MVC项目。