Rya*_*ger 17 asp.net-mvc domain-driven-design dto separation-of-concerns viewmodel
我使用了一个非常标准且保存得很好的DDD模式继承了一个MVC2项目.我也在整个DTO/ViewModel辩论中做了很多阅读.
目前我们的DTO经常像ViewModels一样使用.它老实说并没有对我们正在做的事情产生影响,但我想在升级网站时使用正确的ViewModel.
这是我的问题:
我们的"域"项目模型目前拥有实体并将DTO返回给我的控制器.现在我需要将该DTO映射到ViewModel.我应该在哪里这样做?
我将ViewModel与我们的"Web"项目中的视图保持在一起,因此在域项目中转换DTO - > ViewModel感觉不对.在控制器中执行此操作也感觉不对.
其他人做了什么?
编辑:
这个问题/答案建议在控制器中处理它.很容易想到这一点.
eul*_*rfx 16
DTO通常是特定于技术的.例如,在.NET世界中,您的DTO可能使用DataContract
和DataMember
序列化属性进行修饰.此外,DTO与返回它们的服务一起构成了六角形体系结构的域适配器.它们使您的域适应特定的传输技术(如HTTP),因此它们位于您的域之外.换句话说,域名不应该了解DTO - DTO应该在单独的项目中定义.包含服务的项目应具有将域对象映射到DTO的映射代码.
一个ASP.NET MVC项目在本质上是相似的-它适应您的服务/ DTO的(或域直接对象)的演示技术,HTML尤其如此.因此,DTO不应该知道ViewModels.相反,MVC控制器应该调用DTO和ViewModel之间的映射.这可以通过多种方式完成,但我发现效果最好的是ViewModel中接受DTO的构造函数.此外,在控制器动作保证创建要发送回服务的DTO的情况下,ViewModel可以包含用于基于ViewModel创建DTO的方法.这包含最接近实际数据的ViewModel中的所有映射代码 - 信息专家模式的实例.实现这一点的另一种方法是使用类似AutoMapper的东西,它使用基于约定的映射来避免样板代码.除非有人要求,否则我会考虑过度杀伤.
在许多情况下,ViewModel最终看起来就像DTO,但具有ASP.NET MVC特定的绑定和验证属性.即使这看起来像是对DRY的违反,但这些都是不同的责任.
首先,始终为您的视图使用显式ViewModel,不要将DTO一直传递到View.这是多一点的前期工作,但它可以让你更多的控制权究竟需要在查看哪些数据(这也可以防止像EF框架从侧面加载很多你可能会或可能不会使用额外的数据)
其次,本文概述了Orchestrator模式http://www.simple-talk.com/dotnet/asp.net/never-mind-the-controller,-here-is-the-orchestrator/,它可能只是另一个名称其他一些模式,但我喜欢这种格式.
实质上,您为每个Controller创建一个Orchestrator.Orchestrator接收数据(通常是ViewModel,以及所需的任何其他基本数据类型,特别是来自HttpContext的数据类型),并返回ViewModel(如果View需要,否则返回其他一些返回类型).
这种格式使您能够轻松地对实际逻辑进行单元测试,而无需尝试模拟控制器所需的HttpContext内容.