MVVM 模式:ViewModel 在模型服务器往返后更新

发布于 2024-08-28 10:40:19 字数 664 浏览 5 评论 0原文

我在服务器端有无状态服务和贫血域对象。服务器和客户端之间的模型是POCO DTO。客户端应该成为MVVM。该模型可以是 20 个不同类的大约 100 个实例的图表。客户端编辑器包含各种选项卡页面,所有选项卡页面都实时连接到模型/视图模型。

我的问题是如何在服务器往返之后以良好的方式传播更改。将更改从 ViewModel 传播到 DTO 非常容易。回过头来,可以扔掉旧的 DTO 并用新的 DTO 整体替换它,但这会导致列表/数据模板的大量重绘。

我可以收集服务器端的更改并将它们传输到客户端。但是更改的字段名称将是特定于域/DTO 的,而不是特定于 ViewModel 的。对我来说,映射似乎并不简单。如果我应该在往返之后以命令式的方式执行此操作,则会破坏 viewModel 的 SOC/模块化性。

我正在考虑某种映射规则引擎,例如自动映射器或发出映射器。但它只解决了非常简单的用例。我不知道它将如何映射/传播/转换添加项目到列表或删除。如何识别集合中的实例,以便将值合并到现有实例。它还应该传播验证/错误信息。

也许我应该在 DTO 上实现 INotifyPropertyChanged 并尝试在其上重放服务器端事件?然后将 ViewModel 绑定到它?绑定可以很好地解决集合合并的问题吗? PRISM 的 EventAregator 对此有用吗?有没有事件记录回放组件?

对于具有服务器端逻辑的架构,是否有更好的客户端模式?

I have stateless services and anemic domain objects on server side. Model between server and client is POCO DTO. The client should become MVVM. The model could be graph of about 100 instances of 20 different classes. The client editor contains diverse tab-pages all of them live-connected to model/viewmodel.

My problem is how to propagate changes after server round-trip nice way. It's quite easy to propagate changes from ViewModel to DTO. For way back it would be possible to throw away old DTO and replace it whole with new one, but it will cause lot of redrawing for lists/DataTemplates.

I could gather the server side changes and transmit them to client side. But the names of fields changed would be domain/DTO specific, not ViewModel specific. And the mapping seems nontrivial to me. If I should do it imperative way after round-trip, it would break SOC/modularity of viewModels.

I'm thinking about some kind of mapping rule engine, something like automappper or emit mapper. But it solves just very plain use-cases. I don't see how it would map/propagate/convert adding items to list or removal. How to identify instances in collections so it could merge values to existing instances. As well it should propagate validation/error info.

Maybe I should implement INotifyPropertyChanged on DTO and try to replay server side events on it ? And then bind ViewModel to it ? Would binding solve the problems with collection merges nice way ? Is EventAgregator from PRISM useful for that ? Is there any event record-replay component ?

Is there better client side pattern for architecture with server side logic ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

帅哥哥的热头脑 2024-09-04 10:40:19

通常,我会在模型类中保留对 DTO 的引用。对于多个模型,我确保每个模型都知道如何从 DTO 构建自身,以及如何使用可注入的“保护程序”或其他服务提供者对象来保存自身。当您在模型上调用 Save() 时,携带对 DTO 的引用可以非常轻松地根据模型修改旧的 DTO,然后再将其传回服务。

希望 Save() 操作后对其他对象的任何“更新”都可以在其他 DTO 中进行通信,然后将其加载到 ViewModel 使用的适当模型类中。

这样做的缺点是您确实必须编写映射代码,但这通常是最简单的部分。我不相信这是最好的做事方式,我很乐意阅读其他人的回应。

Typically, I've kept a reference to the DTO in my Model classes. For multiple models, I ensure each model knows how to construct itself from a DTO, as well as how to Save itself using an injectible "saver" or other service provider object. Carrying around a reference to the DTO makes it pretty easy, when you call Save() on the model, to modify the old DTO according to the Model before passing it back to the service.

Hopefully any "updates" to other objects after a Save() operation could be communicated in other DTOs, which should then be loaded into the appropriate Model classes used by your ViewModel.

The downside to this is that you do indeed have to write the mapping code, but this is usually the easiest part. I am not convinced this is the best way to do things and I would appreciate reading others' responses.

深爱不及久伴 2024-09-04 10:40:19

我使用了另一种变体,取得了很大的成功。我们有一个实时 GUI,因此在客户端上重复重绘是不可接受的。

我们让 DTO 了解其属性更改,并向 ViewModel 发出 PropertyChanged 事件,从而重播服务器端事件。

代码编写、单元测试等都很简单。当输入 PropertyChangeListeners (由 ViewModel 实现的接口)时,浏览变得很容易。

此边界还可用于将线程切换到 GUI 工作线程。

I used another variation with a lot of success. We had a real-time GUI, so repetitive redraws on the client were not acceptable.

We made our DTOs aware of their property changes, and emit PropertyChanged events to the ViewModel, therefore replaying server-side events.

Code is straightforward to write, unit test, etc. It becomes easy to browse when PropertyChangeListeners (interfaces implemented by ViewModels) are typed.

This boundary can also be used to switch threads to the GUI worker thread.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文