MVVM Light Messenger的正确使用方法

10

如何正确使用 Messenger 类?我知道它可以用于 ViewModel/View 之间的通信,但在技术/业务服务层中使用它是否是一种好的方法?

例如,一个日志记录/导航服务在构造函数中注册一些消息,并在应用程序中发生这些消息时得到通知。发送方(ViewModel 或 Service)不引用服务接口,只使用 Messenger 发送消息。以下是一个示例服务:

using System;
using System.Windows;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using App.Service.Interfaces;
using GalaSoft.MvvmLight.Messaging;

namespace App.Service
{
    public class NavigationService : INavigationService
    {
        private PhoneApplicationFrame _mainFrame;

        public event NavigatingCancelEventHandler Navigating;

        public NavigationService()
        {
            Messenger.Default.Register<NotificationMessage<Uri>>(this, m => { this.NavigateTo(m.Content); });
        }

        public void NavigateTo(Uri pageUri)
        {
            if (EnsureMainFrame())
            {
                _mainFrame.Navigate(pageUri);
            }
        }

        public void GoBack()
        {
            if (EnsureMainFrame()
                && _mainFrame.CanGoBack)
            {
                _mainFrame.GoBack();
            }
        }

        private bool EnsureMainFrame()
        {
            if (_mainFrame != null)
            {
                return true;
            }

            _mainFrame = Application.Current.RootVisual as PhoneApplicationFrame;

            if (_mainFrame != null)
            {
                // Could be null if the app runs inside a design tool
                _mainFrame.Navigating += (s, e) =>
                {
                    if (Navigating != null)
                    {
                        Navigating(s, e);
                    }
                };

                return true;
            }

            return false;
        }
    }
}

进一步阅读:全局事件被认为是有害的 - nemesv
谢谢,看起来是一个不错的方法。但它并不特定于MVVM Messenger。 - Cybermaxs
1个回答

25

对我来说,消息传递器的主要用途是允许视图模型之间进行通信。比如说你有一个视图模型用于为搜索功能提供业务逻辑,并且有3个视图模型在您的页面/窗口上想要处理搜索以显示输出,使用消息传递器可以以一种松散绑定的方式实现这一点。

获取搜索数据的视图模型会简单地发送一个“搜索”消息,该消息将被当前已注册消费该消息的任何内容所使用。

以下是其中的优点:

  1. 视图模型之间的简单通信,而无需每个视图模型都了解彼此
  2. 我可以更换生产者而不影响使用者
  3. 我可以轻松添加更多的消息使用者
  4. 它使视图模型简洁明了

编辑: 那么,服务方面呢?

视图模型主要用于如何向UI展示数据。他们将您的数据并塑造成可以呈现给View的东西。视图模型从服务中获取其数据。

服务为视图模型提供数据和/或业务逻辑。服务的工作是为业务模型请求提供服务。如果服务需要与其他服务进行通信/使用以完成其工作,应使用依赖注入将其注入服务中。服务通常不会使用消息传递器相互通信。消息传递器非常关于视图模型层面的横向通信。

我见过一件事情,即将消息传递器用作中介,而不是直接将服务注入到视图模型中,而是将消息传递器注入到视图模型中。视图模型订阅事件并接收包含来自该事件的模型的事件。如果您正在接收稳定的更新或者您正在从多个服务接收更新并希望将它们合并成单个流,则此方法非常棒。

如果您正在进行请求/响应类型的请求,则使用消息传递器而不是注入服务没有任何意义,因为您需要编写更多代码来执行此操作,而仅注入服务直接可以使代码易于阅读。

看看你的代码,上面那个。想象一下,如果你必须为每个方法(Navigate,CanNavigate,GoBack,GoForward等)编写一个事件。你最终会得到很多消息。你的代码也会更难理解。


这个家伙抄袭了你的答案吗?http://www.codeproject.com/Tips/696340/Thinking-in-MVVMLight-Messenger - Billy Jake O'Connor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接