【发布时间】:2009-06-10 13:41:00
【问题描述】:
在计算机科学中,我们被教导说,每种方法都应该做一件事,而且只能做一件事。我有点困惑,我们看到像下面这样的 MVC 操作given as examples of good practice:
[AcceptVerbs(HttpVerbs.Post), Authorize]
public ActionResult Edit(int id, FormCollection collection) {
Dinner dinner = dinnerRepository.GetDinner(id);
if (!dinner.IsHostedBy(User.Identity.Name))
return View("InvalidOwner");
try {
UpdateModel(dinner);
dinnerRepository.Save();
return RedirectToAction("Details", new { id=dinner.DinnerID });
}
catch {
ModelState.AddModelErrors(dinner.GetRuleViolations());
return View(new DinnerFormViewModel(dinner));
}
}
基本上这段代码提供了很多功能:
- 定义如何访问操作 - 仅发布
- 定义谁可以访问操作 - 授权
- 访问持久性机制 -dinnerRepository
- 访问状态信息 - (User.Identity.Name)
- 将 NameValueCollection 转换为强类型对象 - UpdateModel()
- 为每个指定 3 个可能的 ActionResult 和内容 - InvalidOwner/Details/Edit 视图
对我来说,一种方法似乎承担了太多责任。这也是一个相当简单的操作,即它不处理常见的场景,例如:
- 检查业务规则 - “从不信任用户输入”
- 导航路径 - 成功保存后总是返回到“详细信息”
- 不同的返回类型 - 有人想从网格中调用“编辑”并需要 JsonResult?
- 更好的错误处理 - 如果在 GetDinner(id) 期间无法访问数据库,则会出现 YSOD
- 构建额外的视图数据 - 下拉列表的 SelectLists
更不用说围绕这种单一方法所需的测试量,即模拟/伪造 FormCollection/UserIdentity/Authorization Provider/Repository/等。
我的问题是我们如何避免在控制器操作中塞进这么多东西?
我倾向于认为"opinions" 是一个很棒的概念,尤其是“Thunderdome 原则”。虽然我非常尊重参与构建 FubuMVC 的人以及他们这样做的原因,但我需要一些我现在可以使用的东西。
编辑 - 看来我是在追求这样的东西 - Opinionated Controller。我需要进一步检查它,因为它适用于 MVC Preview 5,所以我可能需要自己更新它。
【问题讨论】:
标签: asp.net-mvc separation-of-concerns