And*_*ock 23 asp.net-mvc viewmodel
目前我将我的域对象传递给我的视图,并从POST直接绑定到它们.每个人都说这很糟糕,所以我试图添加ViewModel概念.
但是,我找不到一种方法来非常优雅地做到这一点,而且我想知道其他人的解决方案是什么,最终不会出现非常混乱的控制器动作.
一些"添加人"功能的典型过程如下所示:
在控制器动作中执行所有这些操作(忽略GET)肯定不是SRP或DRY.
我试图想办法打破这个过程,以便它遵守SRP,干净,模块化,最重要的是可测试.
人们有什么解决方案?
我一直在尝试使用自定义控制器动作调用器来将关注点分成单独的方法,智能模型绑定器和简单的暴力,但我还没有遇到过满意的解决方案.
PS因为它增加了如此多的复杂性,让我相信为什么我甚至需要打扰
我也感到同样的不适.我唯一的办法是做以下事情:
动作方法如下所示:
public ActionResult Whatever(TViewModel viewModel, TEntity entity)
{
return Save(viewModel, entity);
}
Run Code Online (Sandbox Code Playgroud)
基本控制器具有通用定义,如下所示:
public abstract BaseController<TEntity, TViewModel>
where TEntity : Entity
where TViewModel : ViewModel
Run Code Online (Sandbox Code Playgroud)
构造函数有两个依赖项,一个用于实体存储库,另一个用于模型映射器,如下所示:
protected BaseController(IRepository<TEntity> repository, IMapper<TEntity, TViewModel> mapper)
Run Code Online (Sandbox Code Playgroud)
有了这个,您就可以编写一个受保护的Save方法,该方法可以从子类中的控制器操作中调用,如下所示:
protected ActionResult Save(TViewModel viewModel, TEntity entity)
{
if (!ModelState.IsValid)
return View(viewModel);
_mapper.Map(viewModel, entity);
if (!entity.IsValid)
{
// add errors to model state
return View(viewModel);
}
try
{
_repository.Save(entity);
// either redirect with static url or add virtual method for defining redirect in subclass.
}
catch (Exception)
{
// do something here with the exception
return View(viewModel);
}
}
Run Code Online (Sandbox Code Playgroud)
就可测试性而言,您可以测试传递有效/无效视图模型和实体的save方法.您可以分别测试模型映射器的实现,视图模型的有效状态以及实体的有效状态.
通过使基本控制器通用,您可以为域中的每个实体/视图模型组合重复此模式,如果您要创建许多控制器来执行相同的操作.
我很想知道其他人对此有什么看法.好问题.
MVVM (ViewModel) 模式绝对是一个值得追求的模式,几天前我有一个关于 POSTing back to a action 的类似问题 - 这里是链接:MVVM and ModelBinders in the ASP.NET MVC Framework
结果是您可以使用 Bind 属性回发您想要的复杂类型。
归档时间: |
|
查看次数: |
6430 次 |
最近记录: |