我开始为我的MVC项目实现一个服务层,以减少一些膨胀的控制器(它还具有存储库/单元工作模式)。
我的问题是,如果你有一个包含大量子对象等的页面的复杂视图模型,并且在幕后会发生很多逻辑(为了让你知道原始开发人员编写的控制器有近4000行代码!!)是否可以让多个服务完成他们的工作?或者我应该只有一个大型的ReportService来完成所有工作?
我的控制器开始看起来像这样?如果我继续,我最终可能会调用很多不同的服务来构建视图模型。
这看起来不错还是开始走向错误的方向?
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);
}
答案 0 :(得分:4)
在控制器中安装多个小型服务很好。但是,这里有一件事是错的:
您的服务应该可以通过整个控制器获得,并通过构造函数注入以实现松散耦合。
这样的事情:
private readonly IReportService _reportService;
private readonly IUserService _userService;
public SomeConstructor(IReportService reportService, IUserService userService, etc.)
{
_reportService = reportService;
_userService = userService;
// etc
}
答案 1 :(得分:1)
这看起来确实是一种很好的方法,另一种方法是通过使用Child Actions来解决其中一些问题 - 最好的解决方案将取决于您的特定用例。
例如,如果视图使用ViewModel属性CategoryNavigation
创建一种可能在多个不同视图中有用的导航“窗口小部件”,您可能最好将其拆分为ChildAction例如
[ChildActionOnly]
public ActionResult CategoryNavigationWidget(int reportId)
{
// get the category navigation
var categoryService = new CategoryService();
var categoryNavigation = categoryService.GetCategoryNavigation(report.Id);
return PartialView(categoryNavigation);
}
然后,任何视图都可以通过以下方式呈现该ChildAction:
@{ Html.RenderAction("CategoryNavigationWidget", "Report",
new { reportId = Model.ReportId }); }
这是否是一个好主意可能取决于'小部件'是否可重复使用。