【发布时间】:2011-06-21 16:21:23
【问题描述】:
我正在开发一个大型 Silverlight 应用程序,该应用程序使用双工 Net.TCP 与 WCF 后端通信。我正在将此应用程序从 MVC 方法转移到 MVVM。但是,我正在努力寻找正确的方法来实现我的 ViewModel。我们正在为我们的模型使用 WCF 生成的代理,这非常复杂,涉及几十个类、大量集合和各种多对多关系。例如,一个用户可以属于许多房间,一个房间可以有很多用户,一个用户可以有很多共享文件,每个共享文件可以与用户当前所在的任何房间共享。那种东西。
最重要的是,因为我们在双工模式下使用 WCF,所以对模型的更改可以由最终用户触发,也可以由后端的 WCF 服务触发。换句话说,我们使用的模型比您在各种 MVVM 书籍/文章/博客文章中看到的典型“模型”复杂几个数量级。这就是问题所在,因为让我们的 ViewModel 层与底层 Model 层保持同步变得有点麻烦。
这是一个典型的问题。一个新的“用户”加入了一个“房间”,因此 WCF 服务向房间中的所有其他用户发出“SessionAdded”通知。 SessionAdded 通知带有一个 Session 对象,该对象具有一个链接的 Room 和一个链接的 User 对象。这个从 WCF 服务反序列化的 Room 对象与本地客户端上的 Room 对象基本相同,并且可能具有大部分相同的数据,但它肯定没有所有相同的数据,并且至少有一些数据(比如它的空 Whiteboards 集合)肯定是错误的。所以我们需要以某种方式获取这些传入数据并将其合并到我们现有的模型中。然后我们需要在每个新对象之上创建 ViewModel,和/或使用新对象和/或其数据更新现有 ViewModel。
现在我们通过让各种 ViewModel 响应相关的 WCF 通知事件来处理这个问题,并尽最大努力修复它们的底层模型和相关的视图模型。我们已经找到了一些技巧,比如 SynchronizedObservableCollection(有点像 here),它监视(比如说)Room.Sessions ObservableCollection 并自动创建相应的 SessionViewModels 并将它们放在 RoomViewModel.SessionViewModels 集合中。我们还使用了 ViewModelFactory,它缓存视图模型并确保包装给定 Session 的 SessionViewModel 保持不变,即使底层 Session 对象被更改。 (如果重要的话,我们使用的是视图模型优先的方法,因为我们需要创建新的 UI 元素以响应 WCF 通知触发的 ViewModel 的变化。)
所有这些都有效。基本上。大多数时候。你懂的。但是要维护的代码很多,而且很容易出错。只要您能记住应该发生的事情,单元测试就很方便,但是当您处理完第 20 个级联 CollectionChanged 事件时,很难跟踪所有这些如何组合在一起以及您首先要测试的内容.换句话说,它非常脆弱。
在我看来,这是很多人一定遇到过的那种情况,我很好奇其他人是如何面对它的。我可以想出几种可能让它变得更好的方法:
(1) 将客户端模型视为一种需要保持完全一致的数据库,并实现一个客户端数据访问层,其工作是保持模型一致。对模型的所有更新,无论是来自用户还是服务器,都需要通过这一层。它有点像实体框架,myRoom.Users.Add(myUser) 会自动设置myUser.Room = myRoom,反之亦然,依此类推。 (这尤其是似乎某个地方的某个人应该已经开发的部分,虽然我还没有找到它。)
(2) 依靠Truss 或Obtics 之类的东西,以使所有部分保持同步。不太确定这将如何工作,但从理论上讲,这应该是可能的。
还有……还有什么?我很好奇用于解决此问题的模式或框架。
【问题讨论】:
标签: silverlight wcf mvvm synchronization