silverlight - 保持模型和ViewModel同步的最佳实践

标签 silverlight wcf mvvm synchronization

我正在开发一个大型Silverlight应用程序,该应用程序使用双工Net.TCP与WCF后端通信。我正在将这个应用程序从MVC方法迁移到MVVM。但是,我正在为实现ViewModels的正确方法而苦苦挣扎。我们将WCF生成的代理用于我们的模型,该模型非常复杂,涉及数十个类,大量集合以及各种多对多关系。例如,一个用户可以属于多个房间,一个房间可以具有多个用户,一个用户可以具有多个SharedFiles,并且每个SharedFile可以与该用户当前所属的任何Room共享。诸如此类的事情。

最重要的是,因为我们在双工模式下使用WCF,所以对模型的更改既可以由最终用户触发,也可以由后端的WCF服务触发。换句话说,我们所使用的模型比您在各种MVVM书籍/文章/博客文章中所看到的典型“模型”要复杂几个数量级。这就是问题所在,因为使我们的ViewModel层与基础Model层保持同步变得有点麻烦。

这是一个典型的问题。新的“用户”加入了“房间”,因此WCF服务向房间中的所有其他用户触发“SessionAdded”通知。 SessionAdded通知带有一个Session对象,该对象具有一个链接的Room和一个链接的User对象。从WCF服务反序列化的这个Room对象与本地客户端上的Room对象基本相同,并且可能具有大多数相同的数据,但是它当然不具有所有相同的数据,至少其中一些数据(例如其空白的Whiteboards集合)肯定是错误的。因此,我们需要以某种方式获取这些传入的数据并将其合并到我们现有的模型中。然后,我们需要在每个新对象的顶部创建ViewModel,和/或使用新对象和/或其数据更新现有的ViewModel。

现在,我们正在通过使各种ViewModel响应相关的WCF通知事件来处理此问题,并尽力修复其基础模型和相关的View模型。我们已经找到了一些技巧,例如SynchronizedObservableCollection(有点像here),它监视(说)Room.Sessions ObservableCollection并自动创建相应的SessionViewModels并将其放置在RoomViewModel.SessionViewModels集合中。我们还使用了ViewModelFactory,它可以缓存 View 模型,并确保包装了给定Session的SessionViewModel保持不变,即使基础Session对象被更改了也是如此。 (如果重要的话,我们使用的是viewmodel-first方法,因为我们需要的大部分工作是创建新的UI元素,以响应由WCF通知触发的ViewModel的更改。)

而所有这些工作。基本上。大多数时候。你知道。但是要维护的代码很多,而且很容易出错。只要您能记住应该发生的事情,单元测试就很方便,但是到完成第20个级联CollectionChanged事件的处理时,很难跟踪所有这些如何组合在一起以及首先要测试的内容。换句话说,它们都非常脆弱。

在我看来,这是很多人必须遇到的那种情况,我很好奇其他人如何面对它。我可以想到几种方法来使它变得更好:

(1)将客户端模型视为需要保持完全一致的一种数据库,并实现一个客户端数据访问层,其任务是保持模型一致。无论是来自用户还是服务器,所有对模型的更新都需要经过这一层。这有点像 Entity Framework ,因为myRoom.Users.Add(myUser)将自动设置myUser.Room = myRoom,反之亦然,依此类推。 (尤其是这部分内容似乎应该已经在某个地方发展了,尽管我还没有找到。)

(2)依靠TrussObtics之类的东西,使所有片段保持同步。尚不确定该如何工作,但理论上听起来应该可行。

还有什么?我对用于解决此问题的模式或框架感到好奇。

最佳答案

我了解您的痛苦-我目前正在使用MVVM模式开发复杂的数据可视化应用程序。要问自己一个非常重要的问题是:“ View 模型是否会在您使用的所有地方都增加值(value)?”,换句话说,是否存在将模型层的属性仅转发到 View 的地方?

我经常发现,通常在细节级别(例如,Person对象的属性,Age,Name,Forename)的代码区域中, View 模型实际上根本没有添加任何值,而在更高的类(class)级别中,它通过构造 View /窗口等来增加值(value)。

我倾向于对MVVM采取自适应方法,在顶层(Windows, Pane ,窗体),我总是有一个 View 模型,但是如果 View 模型的各个部分是如此简单,以至于 View 模型没有任何值(value),那么我会将它们公开给他人。直接查看。另外,在某些情况下,您需要直接将模型公开给 View 以提高性能。

最后,如果发现需要重新引入 View 模型来解决棘手的绑定(bind)问题,我写了一个简单的模式mini-MVVM,它应用了本地 View 模型:

http://www.scottlogic.co.uk/blog/colin/2009/08/the-mini-viewmodel-pattern/

希望能有所帮助。

关于silverlight - 保持模型和ViewModel同步的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4903701/

相关文章:

wpf - 如何确定 MVVM 应用程序中的非事件状态?

silverlight - Http 托管 silverlight 应用跨域访问 https 托管服务

java - AsyncTask 显示 WCF 的响应

c# - Windows服务之间如何通信

wpf - Mode = OneWay 直接赋值给 DependencyProperty 的绑定(bind)损坏

c# - 在另一个 ViewModel 中完成数据库更改后,如何 "refresh"我的 ViewModels?

c# - 从 Bing map 中删除图钉

.net - 在 Windows Phone API 中反射 DLL (SIlverlight)

c# - MVVM 必须使用 DataTemplates 吗?

c# - 缺少基于任务的 WCF 服务的帮助说明