Asp.net mvc ASP.NET MVC-服务层,每个控制器操作中的单个或多个服务?
我开始在我的MVC项目中实现一个服务层,以精简一些臃肿的控制器(它还具有repository/unitofwork模式) 我的问题是,如果你有一个复杂的视图模型,用于一个包含很多子对象等的页面,并且后台有很多逻辑(让你知道,最初的开发人员编写的控制器有将近4000行代码!!)让多个服务停止工作可以吗?或者我应该只拥有一个大的ReportService来完成一切 我的控制器开始像这样了?如果我继续下去,我可能会调用很多不同的服务来构建视图模型 这看起来还好吗,还是开始走错方向了Asp.net mvc ASP.NET MVC-服务层,每个控制器操作中的单个或多个服务?,asp.net-mvc,asp.net-mvc-3,Asp.net Mvc,Asp.net Mvc 3,我开始在我的MVC项目中实现一个服务层,以精简一些臃肿的控制器(它还具有repository/unitofwork模式) 我的问题是,如果你有一个复杂的视图模型,用于一个包含很多子对象等的页面,并且后台有很多逻辑(让你知道,最初的开发人员编写的控制器有将近4000行代码!!)让多个服务停止工作可以吗?或者我应该只拥有一个大的ReportService来完成一切 我的控制器开始像这样了?如果我继续下去,我可能会调用很多不同的服务来构建视图模型 这看起来还好吗,还是开始走错方向了 public Vi
public ViewResult Index(int? reportId)
{
// get the base report object
var reportService = new ReportService();
var report = reportService.GetByReportId(reportId);
var model = Mapper.Map<Report, ReportViewModel>(report);
// get the current active user
var userService = new UserService();
var user = userService.GetCurrentUser();
model.User = Mapper.Map<User, ReportViewModel.UserViewModel>(user);
// get the first unread message
var messageService = new MessageService();
var message = messageService.GetFirstUnread(user.Id);
model.Message = Mapper.Map<Message, ReportViewModel.MessageViewModel>(message);
// get the category navigation
var categoryService = new CategoryService();
var categoryNavigation = categoryService.GetCategoryNavigation(report.Id);
model.CategoryNavigation = Mapper.Map<IEnumerable<Category>, IEnumerable<ReportViewModel.CategoryNavigationViewModel>>(categoryNavigation);
return View(model);
}
公共视图结果索引(int?reportId)
{
//获取基本报表对象
var reportService=new reportService();
var report=reportService.GetByReportId(reportId);
var model=Mapper.Map(报告);
//获取当前活动用户
var userService=new userService();
var user=userService.GetCurrentUser();
model.User=Mapper.Map(用户);
//获取第一条未读消息
var messageService=new messageService();
var message=messageService.GetFirstUnread(user.Id);
model.Message=Mapper.Map(Message);
//获取类别导航
var categoryService=新的categoryService();
var categoryNavigation=categoryService.GetCategoryNavigation(report.Id);
model.CategoryNavigation=Mapper.Map(CategoryNavigation);
返回视图(模型);
}
控制器中可以有多个小型服务。然而,这里有一件事是错误的: 您应该通过整个控制器提供服务,并通过构造函数注入服务,以实现松散耦合 比如说:
private readonly IReportService _reportService;
private readonly IUserService _userService;
public SomeConstructor(IReportService reportService, IUserService userService, etc.)
{
_reportService = reportService;
_userService = userService;
// etc
}
这看起来确实是一个好方法,另一种方法是使用子操作将其中的一部分分割开来——不过,最好的解决方案将取决于您的特定用例 例如,如果视图正在使用ViewModel属性
CategoryNavigation
创建一种导航“小部件”,它可能在多个不同的视图中有用,那么最好将其拆分为子操作,例如
[ChildActionOnly]
public ActionResult CategoryNavigationWidget(int reportId)
{
// get the category navigation
var categoryService = new CategoryService();
var categoryNavigation = categoryService.GetCategoryNavigation(report.Id);
return PartialView(categoryNavigation);
}
然后,任何视图都可以通过以下方式呈现该子动作:
@{ Html.RenderAction("CategoryNavigationWidget", "Report",
new { reportId = Model.ReportId }); }
这是否是一个好主意可能取决于“小部件”是否可重用。事实上,这看起来相当干净。控制器方法应被视为“配线架”,几乎没有业务逻辑。这里就是这样。很明显,您在同一页面上显示来自不同来源的不同类型的信息(很像“仪表板”视图),因此,我在这里看到的相对复杂性是完全合理的。如果您担心它的复杂性,您可以考虑通过Ajax加载每个值,返回部分视图,并对每个服务执行操作等。这样,如果需要,您可以潜在地拆分控制器。这取决于需要多少服务-如果您考虑的服务超过6-8,比如说,最好实现按需依赖关系解析,以避免使用具有大量参数的构造函数。不过你是对的。然而,当您需要几十个服务时,这可能意味着您应该将控制器“拆分”为不太通用的控制器。