访问视图中的域对象

时间:2009-11-12 17:19:31

标签: asp.net-mvc domain-driven-design

如果我不想公开我的域对象的内部状态,但我需要显示它们,我可以想到三种方法。 哪一项最“正确”(如果有的话)。

  1. “DTO / ViewModel方法”。 这似乎是一种流行的方法 在ASP.NET MVC世界中(特别是 使用AutoMapper)。
  2. 的 “装饰者的方法”。如果我有 “客户”实体,我装饰它 有一个“DisplayableCustomer”谁可以 访问内部状态 客户(在大多数语言中 我已经处理过)。
  3. “界面 接近“。我在哪里做的事情 这样:

    class Customer {
        ....
        public void renderWith(CustomerRenderer renderer) {
             renderer.renderCustomer(address,name);
        } 
    }
    
    interface CustomerRenderer {
        public void renderCustomer(Address address, Name name);
    }
    

1 个答案:

答案 0 :(得分:3)

我投票支持并广泛使用您的#1选项。原因如下:

  • 允许使用复杂的视图模型,例如组合我的域对象的多个列表。认为PostViewModel有一个Post元素和一个挂着它的IList容器。
  • 在我当前的项目中,我们已经将域验证抽象到了我们自定义的ViewModel中的位置,并在表单上进行了一些灵活的Ajax验证。
  • 虽然这个概念没有在模型上直接暴露你的域对象,但我没有问题挂起PostViewModel的属性。

最后一点是ViewModels概念真正存在的原因。将您的Domain对象一直暴露到您的UI甚至视图都不违反DDD - 这是设计和期望的DDD和UI概念。您只公开要使用的域中的对象,并使用服务和基础结构锁定/保持其状态。因此,您不会违反在UI中使用实际的Domain对象。

当您涉及UI的MVC概念,并尝试渲染页面/位置的特定视图时。您可能(并且将)拥有可能与域无关的其他显示元素,例如仅适用于UI的Progress Bar。进度条仅适用于UI和APplication层。它与您的域名无关。

因此,我接受的DDD解决方案是在Application / UI层中使用hybird对象,该对象可以容纳许多对象:Domain对象和Application对象都要为该特定View呈现。这是ViewModel的概念,其核心原因是。

可以将ViewModel概念视为DDD术语中的应用层非业务对象。


稍微讨论一下主题并讨论一种特定技术,ASP.NET MVC还有其他功能可以帮助使这个概念很好地协同工作。它并没有直接内置到ASP.NET MVC中,而是作为Microsoft的一个名为Futures项目的附加程序集提供。

Check out my blog post about a couple of features,最有用的功能是RenderAction扩展方法:

http://eduncan911.com/blog/html-renderaction-for-asp-net-mvc-1-0.aspx

这是一个非常强大的概念,可以旋转底层控制器并调用action方法。这样做大大简化了我们的ViewModel,只关心它们正在渲染的视图。我不再需要附加侧边栏控件或其他与视图无关的常用数据框,导航栏等内容。

RenderAction与RenderPartial的不同之处在于纯DDD:它允许您将业务逻辑移回到它所属的Controller中。控制器调用正确的视图来呈现它的显示。这严格遵循DDD和MVC概念。

微软已声明RenderAction将于明年发布时成为ASP.NET MVC 2.0的一部分。

抱歉咆哮......