正确使用MVVM Light Messenger的方法 [英] Proper way of using MVVM Light Messenger

查看:736
本文介绍了正确使用MVVM Light Messenger的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

What is the proper way to use Messenger class ? I know it can be used for ViewModels/Views communications, but is it a good approach to use it in for a technical/business service layer ?

例如,日志记录/导航服务在构造函数中注册一些消息,并知道这些消息何时在应用程序中发生.发送方(ViewModel ou Service)不引用服务接口,而仅引用用于发送消息的Messenger.这是一个示例服务:

For example, a logging/navigation service registers for some messages in the constructors and is aware when these messages occurs in the app. The sender (ViewModel ou Service) does not reference the service interface but only messenger for sending messages. Here is a sample 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;
        }
    }
}

推荐答案

对我而言,Messenger的主要用途是因为它允许在ViewModels之间进行通信.假设您有一个用于向搜索功能提供业务逻辑的视图模型,并在页面/窗口上有3个视图模型要处理搜索以显示输出,那么Messenger将是在松散绑定中进行此操作的理想方法方式.

For me, the main use of a messenger is because it allows for communication between viewModels. Lets say you have a viewmodel that is used to provide business logic to a search function and 3 viewmodels on your page/window that want to process the search to show output, the messenger would be the ideal way to do this in a loosely-bound way.

获取搜索数据的viewmodel只会发送搜索"消息,该消息将被当前注册使用该消息的任何对象所消耗.

The viewmodel that gets the search data would simply send a "search" message that would be consumed by anything that was currently registered to consume the message.

这里的好处是:

  1. 视图模型之间的轻松通信,而每个视图模型不必彼此了解
  2. 我可以在不影响消费者的情况下换出生产者.
  3. 我可以毫不费力地添加更多的消息使用者.
  4. 它使视图模型保持简单

那服务呢?

ViewModels都是关于如何将数据呈现给UI的.他们将您的数据整理成可以呈现给View的内容. ViewModels从服务中获取数据.

ViewModels are all about how to present data to the UI. They take your data and shape it into something that can be presented to your View. ViewModels get their data from services.

服务将数据和/或业务逻辑提供给ViewModel.服务工作是为业务模型请求提供服务.如果服务需要通信/使用其他服务来完成其工作,则应使用依赖项注入将这些服务注入服务中.服务通常不会使用Messenger相互通信. Messenger在视图模型级别上非常注重水平通信.

A service provides the data and/or business logic to the ViewModel. The services job is to service business model requests. If a service needs to communicate/use other services to do its job these should be injected into the service using dependency injection. Services would not normally communicate with each other using a messenger. The messenger is very much about horizontal communication at the viewmodel level.

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

One thing I have seen done is to use a messenger as a mediator, where instead of injecting the service directly into a viewmodel the messenger is injected into the viewmodel instead. The viewmodel subscribes to an event and receives events containing models from the event. This is great if you're receiving a steady flow of updates or you're receiving updates from multiple services that you want to merge into a single stream.

在执行请求/响应类型请求时,使用Messenger而不是注入服务没有任何意义,因为您必须编写更多代码才能做到这一点,而这仅是注入服务即可直接,这使得代码难以阅读.

Using a messenger instead of injecting a service when you're doing request/response type requests doesn't make any sense as you'll have to write more code to do this that you'd have to write just injecting the service directly and it makes the code hard to read.

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

Looking at your code, above. Imagine if you had to write an event for each method on there (Navigate, CanNavigate, GoBack, GoForward, etc). You'd end up with a lot of messages. Your code would also be harder to follow.

这篇关于正确使用MVVM Light Messenger的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆