【问题标题】:What should go into the model and the view-model?模型和视图模型应该包含什么?
【发布时间】:2011-11-07 15:19:17
【问题描述】:

我正在开发一个 WPF 客户端,它与使用 NHibernate 将数据保存在数据库中的 WCF Web 服务进行交互。

客户端将对 UI 使用 MVVM 设计模式,并通过发送和接收 DTO 与 WCF 服务进行交互。

据我了解,View-Model 中应仅包含演示数据和逻辑,而 Model 应包含应用程序的数据和业务逻辑。

现在让我们以客户端中的登录屏幕为例。

  • 视图将代表登录屏幕本身,其数据上下文将是视图模型。
  • View-Model 将保存 Model 的一个实例,并通过实现 INotifyProperty 接口来更新 View。

这是我的问题:模型中究竟应该包含什么?

它是否应该使用诸如 MEF 之类的依赖注入容器来保存对 WCF 代理接口的引用?

基本上,用户将输入用户名和密码,由于数据绑定,这将更新视图模型中的属性。每当用户按下视图上的“登录”按钮时,都会向视图模型发送一个命令,视图模型又将其转发给模型。然后模型使用代理接口与 WCF Web 服务进行通信。

这种方法正确吗?如果不是,那么 Model 和 View-Model 中究竟应该包含哪些内容?

【问题讨论】:

  • 为什么 View-Model 会得到视图的实例?
  • 视图是否应该改为获取 VM 的实例..?我见过许多 MVVM 模式的实现,或者 VM 有 View 的实例,反之亦然。您将如何实施该模式?换句话说,我应该创建 View 并注入 VM,还是应该创建 VM 并注入 View ?
  • 视图将 View-Model 作为 DataContext。所以 View 知道 ViewModel。通常你不需要知道来自 ViewModel 的视图。如果 ViewModel 获得了 View 的一个实例,你可能会有一个紧耦合
  • 明白,谢谢。因此,创建视图的新实例并显示它也会创建 View-Model 的实例,因为它是数据上下文。 View-Model 是否应该持有 Model 的实例?

标签: .net wcf web-services mvvm wcf-client


【解决方案1】:

如果您查看Karls Shiffletts blog,您会发现关于 MVVM 层的良好图表。
我会说你的实现对我来说看起来不错。

这取决于您的实现,最可能的是您将切换 ViewModel 并为 ViewModel 提供一个 DataTemplate(视图)。这个 CodeProject 链接显示了一个很好的实现:Creating an Internationalized Wizard in WPF

【讨论】:

  • 这张图很棒,但我不同意当前的实现还可以。通过Model 访问 WCF 服务的建议是个坏主意。访问 WCF 服务应该通过ViewModel,而不是Model
  • 感谢 WaltiD 的链接,我也喜欢这个图表。
【解决方案2】:

Models 不应包含数据访问或任何超出验证其数据的业务逻辑。它们是数据对象,应该只包含数据和验证。

您的ViewModels 负责运行您的应用程序,这包括填充数据对象(模型)、更改它们、保存/删除它们以及将它们(和其他相关属性)提供给View

如果您有兴趣,我有一个简单的 MVVM 示例 here。最顶部有一个定义,它定义了 ModelViewModel 相比应该进入的内容

【讨论】:

  • 谢谢瑞秋,这正是我想知道的。我会看看你的例子。只是想知道,View Model 会从 Model 中获取数据,将其转换为可以发送到 Web Service 的格式,然后调用 Web Service 吗?
  • @Hussein 是的。有时我的模型是 WCF 服务返回的对象,有时我使用 AutoMapper 之类的东西将 Model 映射到 DTO,反之亦然。
  • 感谢您的澄清,我开始掌握这些概念。至于我最初帖子中的登录屏幕示例,我相信我会走这条路:视图的 DataContext 将是视图模型。每当用户按下视图上的“连接”按钮时,都会使用一个命令来调用视图模型,视图模型反过来将使用命令接收的参数创建一个 DTO(即:模型)。然后视图模型将继续联系 Web 服务。如果 Web 服务返回错误,视图模型将通过更新视图绑定到的属性来提醒视图。
【解决方案3】:

MVVM 中的 ViewModel 是 classic MVC 中的 ApplicationModel 和 Controller 的组合。因此,它负责连接到服务以查询数据以显示和调用对服务的操作。

工作流程应该是这样的:

  1. Lo​​ginViewModel 已创建并获取 WCF 服务的句柄(理想情况下,您应该使用 DI 将 WCF 服务作为 ILoginService 注入)
  2. 用户输入绑定到虚拟机相应属性的用户名和密码,点击绑定到虚拟机委托命令的登录。
  3. 在命令处理程序中,VM 运行验证(例如,确保已设置用户名和密码)
  4. VM 调用 ILoginService 上的 LoginUser 并传递用户名和密码(调用 WCF 服务上的操作。

模型不应该知道服务等。从技术上讲,您在客户端使用纯 DTO,因此它应该具有最少的逻辑,在服务背后,应该有一个更丰富的模型,它确实具有业务逻辑和验证。

【讨论】:

  • 太好了,正是我需要知道的!谢谢!
  • “MVVM 中的 ViewModel 是经典 MVC 中 ApplicationModel 和 Controller 的组合”+1 - 这是一个很好的总结方式。
猜你喜欢
  • 1970-01-01
  • 2013-05-07
  • 1970-01-01
  • 2012-01-12
  • 2018-04-05
  • 2019-05-31
  • 2012-09-15
  • 1970-01-01
  • 2015-01-09
相关资源
最近更新 更多