繁体   English   中英

MVVMLight :这是使用 Messenger 的正确方法吗?

[英]MVVMLight : is this the right way to use the Messenger?

我有一个管理客户和地址的经典业务应用程序。

有选项卡项(Id、GenericInfo 等),每个项都有自己的 ViewModel。

有一个 MainViewModel 处理客户端及其地址的保存和加载命令。

我们从 WCF 服务中检索数据。 从每个 WCF 函数接收/发送的数据聚合在不同的容器中。


在我的 MainViewModel 中,我创建了一个 SaveContainer,然后将它与 Messenger 一起发送。

    public void Save()
    {
        var container = new SaveContainer();

        MessengerInstance.Send(container);

        //the container is now populated and ready to be sent via WCF

        Console.WriteLine(container.User.Name);
        Console.WriteLine(container.Address.StreetName);
        Console.WriteLine(container.Address2.StreetName);
    }

在我的 UserViewModel 中注册了该容器,然后视图模型用它拥有的数据(用户)填充它。

    public UserViewModel()
        : base(Messenger.Default)
    {
        User = new User();

        MessengerInstance.Register<SaveContainer>(this, (x) => x.User = User);
    }

在我的 AddressViewModel 中,我也这样做。

    public AddressViewModel()
        : base(Messenger.Default)
    {
        Address = new Address();
        Address2 = new Address() { StreetName = "Washington Street" };

        MessengerInstance.Register<SaveContainer>(this, x =>
        {
            x.Address = Address;
            x.Address2 = Address2;
        });
    }

当我必须加载数据时,我也会这样做。


在我发送消息后,我假设每个注册的 ViewModel 都收到了消息并处理了它。 我假设错了吗? 您认为这种方式是使用 Messenger 的正确方式吗? 你会改进什么?

没有使用信使的正确方法。 但是,您必须考虑到该消息由所有注册该消息的收件人处理,而不仅仅是预期的子集。 此外,在使用消息传递时,您无法控制消息处理何时完成,现在您是否会在所有收件人处理完消息时收到通知。 此外 - 取决于信使的实现 - 可以并行处理消息。

因此,您的方法(以及@cadrell0 使用回调的扩展名)的问题在于您不知道所有收件人何时都处理了消息。 使用回调,您将获得处理消息的每个接收者的回调(即 n 个接收者 n 个回调)。

那么如何检查所有收件人何时处理完邮件?

  • 您使用计数器来确定有多少收件人已回电 - 这很容易出错,因为您可能会注册另一个邮件收件人,这会弄乱您的系统。
  • 另一种方法是验证保存容器并在它完成后继续处理 - 但这可能会导致竞争条件,因为您可能认为所有收件人都已处理消息并继续,但后来一个迟到的收件人调用并使您的保存容器无效。 .. 不好。

在我看来,消息传递更像是一种通知机制,即您通知某些收件人发生了某些事情。 如果您知道并且可以确保只有一个收件人,您甚至可以按照您描述的方式使用它,但是一旦涉及多个收件人,就会导致上述问题。

那么这会让你在哪里......在你的szenario中我倾向于将视图模型设计为“相关”(即主视图模型知道用户视图模型地址视图模型 - 或者主视图模型知道用户如果更合适的话,视图模型又知道地址视图模型)。 通常,我还会设计一个模型来保存我必须处理的工作单元(在您的情况下是 SaveContainer)。 然后所有的视图模型都是从这个模型构建的,并将它们的数据写入其中。 在正常情况下,此工作单元是您从数据存储服务中获得的内容,而数据存储又会在单个事务中保存这些内容。

但同样,MVVM 没有正确的方法!

如果我需要在收件人回复消息后做某事,我会在我的消息中包含回调。 当接收者完成时,它执行回调。 向回调添加参数允许接收者向发送者发送数据。 这也允许接收者执行异步操作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM