我继承了一个MVC2项目,使用了一个漂亮的标准和妥善保存的DDD模式.在整个DTO / viewmodel辩论中,我一直在做很多阅读.
目前,我们的DTO通常用于viewmodels.诚然,我们正在做的事情并没有什么变化,但是当我们升级网站时,我想使用适当的viewmodels.
这是我的问题:
我们的“领域”项目的模型目前持有实体并将DTO返回给我的控制器.现在我需要将该DTO映射到viewmodel.我该怎么办?
>在控制器中?
>在域名项目中?
>其他地方?
我将viewmodels与我们的“Web”项目中的视图保持一致,所以转换DTO感觉错误 – > viewmodel在域项目中.在控制器中也觉得错误.
别人做了什么?
编辑:
This question/answer 建议在控制器中处理它.肯定会很容易想到这一点.
解决方法
DTO通常是技术特定的.例如在.NET世界中,您的DTO可能使用DataContract和DataMember序列化属性进行装饰.此外,DTO与返回它们的服务一起构成了一个适用于
hexagonal architecture的域的适配器.它们将您的域调整到特定的传输技术,如HTTP,并且它们居住在您的域外.换句话说,域不应该知道DTO – DTO应该在一个单独的项目中定义.包含服务的项目应具有将域对象映射到DTO的映射代码.
ASP.NET MVC项目本质上类似,它将您的服务/ DTO(或域对象直接)适应于演示技术,特别是HTML.因此,DTO不应该意识到viewmodels.相反,MVC控制器应该调用DTO和viewmodels之间的映射.这可以通过各种方式完成,但是我发现最有效的是在viewmodel中接受DTO的构造函数.此外,在控制器动作保证创建要发送回服务的DTO的情况下,viewmodel可以包含基于viewmodel创建DTO的方法.它包含最接近实际数据的viewmodel中的所有映射代码 – 一个information expert pattern的一个实例.另一种实现此方法的方法是使用像AutoMapper这样的方法,它使用基于约定的映射来避免样板代码.除了我以外,除了要求之外,我会考虑过度杀戮.
在许多情况下,您的viewmodel最终看起来像DTO,但使用ASP.NET MVC具体的绑定和验证属性.尽管这似乎违反了DRY,但这些都是独立的责任.