正确使用MVVM Light Messenger的方法

正确使用MVVM Light Messenger的方法,mvvm,mvvm-light,messaging,Mvvm,Mvvm Light,Messaging,使用Messenger类的正确方法是什么? 我知道它可以用于ViewModels/Views通信,但在技术/业务服务层中使用它是一种好方法吗 例如,日志/导航服务在构造函数中注册一些消息,并在应用程序中出现这些消息时进行感知。发送方(ViewModel ou服务)不引用服务接口,而仅引用messenger来发送消息。以下是一个示例服务: using System; using System.Windows; using System.Windows.Navigation; using Micro

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

例如,日志/导航服务在构造函数中注册一些消息,并在应用程序中出现这些消息时进行感知。发送方(ViewModel ou服务)不引用服务接口,而仅引用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;
        }
    }
}
使用系统;
使用System.Windows;
使用System.Windows.Navigation;
使用Microsoft.Phone.Controls;
使用App.Service.Interfaces;
使用GalaSoft.MvvmLight.Messaging;
名称空间App.Service
{
公共类导航服务:INavigationService
{
专用电话应用框架\u主机;
公共事件导航CancelEventHandler导航;
公共导航服务()
{
Register(this,m=>{this.NavigateTo(m.Content);});
}
public void NavigateTo(Uri页面Uri)
{
if(inframe())
{
_大型机导航(pageUri);
}
}
公开作废GoBack()
{
if(inframe()
&&_大型机(CanGoBack)
{
_mainFrame.GoBack();
}
}
二等兵
{
如果(_mainFrame!=null)
{
返回true;
}
_mainFrame=Application.Current.RootVisual作为PhoneApplicationFrame;
如果(_mainFrame!=null)
{
//如果应用程序在设计工具内运行,则可能为null
_大型机。导航+=(s,e)=>
{
如果(导航!=null)
{
航行(s,e);
}
};
返回true;
}
返回false;
}
}
}

对我来说,messenger的主要用途是允许viewModels之间进行通信。假设您有一个viewmodel,用于为搜索功能提供业务逻辑,页面/窗口上有3个viewmodel希望处理搜索以显示输出,messenger将是以松散绑定的方式实现这一点的理想方式

获取搜索数据的viewmodel只需发送一条“搜索”消息,该消息将被当前注册以使用该消息的任何对象使用

这里的好处是:

  • viewmodels之间的轻松通信,无需每个viewmodel相互了解
  • 我可以在不影响消费者的情况下更换生产商
  • 我可以不费吹灰之力就添加更多的消息消费者
  • 它使viewmodels保持简单
  • 编辑: 那么,服务呢?

    ViewModels都是关于如何向UI显示数据的。他们把你的数据塑造成可以呈现在你眼前的东西。ViewModels从服务获取数据

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

    我看到的一件事是将messenger用作一个服务,而不是将服务直接注入viewmodel,而是将messenger注入viewmodel。viewmodel订阅事件并从该事件接收包含模型的事件。如果您正在接收稳定的更新流,或者您正在接收来自多个要合并到单个流中的服务的更新,那么这非常好

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


    查看上面的代码。想象一下,如果您必须为其中的每个方法(导航、CanNavigate、GoBack、GoForward等)编写一个事件。你会收到很多信息。您的代码也将更难理解。

    进一步阅读:谢谢,这似乎是一个愚蠢的方法。但这并不是MVVM信使特有的猜测这家伙窃取了你的答案?