不传递实体查看的好处

时间:2011-10-23 19:56:23

标签: asp.net-mvc architecture view mapping coupling

我经常看到人们告诉你不应该将实体传递给你的View。他们说你应该使用DTO / VO / ViewModel / AnyOtherThingYouWant,因为使用实体会增加耦合。 忽略我确实需要一些额外逻辑的时刻(或者我不需要所有属性),我没有看到这样做的任何好处。例如,请考虑以下类:

public class Contact {
    public int Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
    public string Phone { get; set; }
}

我看到很多代码创建了另一个类,如下所示:

public class ContactDTO {
    public int Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
    public string Phone { get; set; }
}

在视图中使用它然后执行此操作:

someMapper.Map(contactDto).To<Contact>();

我看不出这比使用Contact类有多好,因为View会耦合到一个耦合到实体类的类。因此,一个中的每个变化都应该复制到另一个中。从我的观点来看,“中间”对象只是为了增加复杂性,而不是真正的价值。 我知道没有“一刀切”的解决方案(有时候,使用中间对象会有意义),但我们真的需要添加这样的代码吗?有什么真正的好处?

2 个答案:

答案 0 :(得分:4)

以这种方式思考:视图是对您的域的投影。它是您的业务模型的具体表示。因此,您需要使用一个代表此投影的视图模型。它可以是域模型的子集,但如果视图需要,它也可以是多个域模型的聚合。您提供的示例只是一个特定情况,由于此特定视图的要求,域模型和视图模型之间存在1:1映射。但这只是一个具体的观点。我想您的应用程序有很多视图和不同的域实体表示。

有许多视图特定的事情会使您的域模型不适合,因此需要视图模型。例如验证。在某些视图中可能需要给定的域模型属性,而在另一个视图中则不需要(考虑创建/更新视图中的Id属性)。如果您不使用视图模型但是让您的Create控制器操作直接采用域模型,那么如果您的域模型Id属性使用Required属性进行修饰,则会出现问题。

还有很多其他例子。如果我在开发ASP.NET MVC应用程序时给你一个建议,那就是:始终为你的视图定义特定的视图模型,永远不要将域模型传递给视图/从视图中传递域模型,即使在你拥有的情况下也是如此域模型和视图模型之间的1:1映射。

答案 1 :(得分:3)

引用的方法是一种纯粹主义。如果您不需要对域对象进行转换(缩小,合并等),并且它们可以直接在您的视图中使用,请使用它们 - 您可以稍后通过重构来引入DTO(如有必要)

所以你必须考虑到Darin Dimitrov所说的内容,但请记住,DTO和类似的东西可以让你的工作更轻松。我记得我参与过的一个项目 - 超过90%的DTO是域对象的一对一副本 - 这完全没用,只会增加维护成本。