正确使用MVVM Light Messenger的方法

时间:2012-08-31 07:01:56

标签: mvvm mvvm-light messaging

使用Messenger课程的正确方法是什么? 我知道它可以用于ViewModels / Views通信,但它是一个很好的方法用于技术/业务服务层吗?

例如,日志记录/导航服务为构造函数中的某些消息注册,并且知道应用程序中何时出现这些消息。发件人(ViewModel ou Service)不引用服务接口,而只引用发送消息的信使。这是一个示例服务:

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;
        }
    }
}

1 个答案:

答案 0 :(得分:23)

对我来说,信使的主要用途是因为它允许viewModel之间的通信。假设您有一个用于为搜索功能提供业务逻辑的viewmodel,以及您希望处理搜索以显示输出的页面/窗口上的3个视图模型,信使将是在松散边界中执行此操作的理想方式方式。

获取搜索数据的viewmodel只会发送一条“搜索”消息,该消息将被当前注册用于使用该消息的任何内容消耗。

这里的好处是:

  1. 视图模型之间的轻松通信,而每个视图模型都不必彼此了解
  2. 我可以在不影响消费者的情况下换掉生产者。
  3. 我可以毫不费力地添加更多消息使用者。
  4. 它使viewmodels保持简单
  5. 编辑: 那么,服务呢?

    ViewModels是关于如何向UI呈现数据的。他们会将您的数据整理成可以呈现给您的视图的内容。 ViewModels从服务中获取数据。

    服务为ViewModel提供数据和/或业务逻辑。服务工作是为业务模型请求提供服务。如果服务需要通信/使用其他服务来完成其工作,则应使用依赖注入将这些服务注入服务。服务通常不会使用信使彼此通信。信使非常关注视图模型级别的水平通信。

    我所看到的一件事是将信使用作mediator,而不是将服务直接注入视图模型,而是将信使注入到视图模型中。 viewmodel订阅事件并接收包含事件模型的事件。如果您收到稳定的更新流,或者您要从要合并到单个流中的多个服务接收更新,那就太棒了。

    当您执行请求/响应类型请求时,使用信使而不是注入服务没有任何意义,因为您必须编写更多代码来执行此操作,您必须编写注入服务直接使代码难以阅读。

    查看上面的代码。想象一下,如果你必须在那里为每个方法写一个事件(Navigate,CanNavigate,GoBack,GoForward等)。你最终会收到很多消息。你的代码也很难遵循。