如果我不想公开我的域对象的内部状态,但我需要显示它们,我可以想到三种方法。 以下哪个是最“正确”的(如果有的话?)。
- “DTO/ViewModel 方法”。 这似乎是一种流行的方法 在 ASP.NET MVC 世界中(特别是 使用 AutoMapper)。
- 的 “装饰方法”。如果我有一个 “客户”实体,我装饰它 有一个“DisplayableCustomer”谁可以 访问的内部状态 客户(在大多数语言中 我处理过)。
“接口(interface) 方法”。我在哪里做类似的事情 这个:
class Customer { .... public void renderWith(CustomerRenderer renderer) { renderer.renderCustomer(address,name); } } interface CustomerRenderer { public void renderCustomer(Address address, Name name); }
最佳答案
我投票支持并广泛使用您的第一选项。几个原因:
- 允许复杂的 View 模型,例如组合我的域对象的多个列表。想象一个带有 Post 元素的 PostViewModel 和一个悬卡在它上面的 IList 容器。
- 在我当前的项目中,我们已经将域验证抽象到它冒泡到我们的自定义 ViewModel 中的地方,并对表单进行一些巧妙的 Ajax 验证。
- 虽然这个概念不会直接在模型上公开您的域对象,但我可以毫无问题地将 Post 卡在我的 PostViewModel 的属性之外。
最后一点是 ViewModels 概念真正存在的原因。将您的域对象一直暴露到您的 UI 甚至 View 并不违反 DDD - 这是 DDD 和 UI 概念的设计和预期。您只公开域中的对象以供使用,并通过服务和基础架构锁定/保留它们的状态。因此,您没有违反在 UI 中使用实际域对象的规定。
当您将 MVC 概念用于您的 UI 并尝试呈现页面/位置的特定 View 时。您可能(并且将会)拥有与域完全无关的其他显示元素,例如 Progress Bar这仅适用于用户界面。进度条只与 UI 和应用层有关。它与您的域无关。
因此,我接受的 DDD 解决方案是在应用程序/UI 层中使用一个混合对象,它可以容纳多个对象:领域对象和应用程序对象,以呈现一个特定的 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
这是一个非常强大的概念,可以启动底层 Controller 并调用操作方法。这样做极大地简化了我们的 ViewModel,使其只关心它们正在渲染的 View 。我不再需要附加与 View 无关的内容,例如边栏控件或其他常用数据框、导航栏等。
出于纯粹的 DDD 原因,RenderAction 与 RenderPartial 不同:它允许您将业务逻辑移回到它所属的 Controller 中。并且 Controller 调用正确的 View 来呈现它的显示。这严格遵循 DDD 和 MVC 概念。
Microsoft 已声明 RenderAction 将在明年发布时成为 ASP.NET MVC 2.0 的一部分。
对不起,我的咆哮......
关于asp.net-mvc - 访问 View 中的域对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1723889/