在C#中实现消息/订阅机制 [英] Implementing a message/subscription mechanism in C#

查看:1526
本文介绍了在C#中实现消息/订阅机制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用MVVM模式来构建一个WPF应用程序。在此问题的答案后,我已经设置了一个 ModelProviderService 将模型显示为属性。服务的消费者是观看模式,即他们从服务中提取模型,而不是自己实例化。

  class ModelProviderService { 

private LoginModel loginModel;
public LoginModel LoginModel {
get {return loginModel; }
set {loginModel = value; }
}

private ProjectsModel projectsModel;
public ProjectsModel ProjectsModel {
get {return projectsModel; }
set {projectsModel = value; }
}

public ModelProviderService(){
loginModel = new LoginModel();
projectsModel = new ProjectsModel();
}
}

现在,这里会发生什么:




  • viewmodel会更改例如的属性 LoginModel 属性。

  • viewmodel通过设置其属性将model属性推回服务: modelService.LoginModel.MyProperty = localLoginModel.MyProperty; / li>
  • 该服务将发布一条消息:嘿,我的类型为$ code> LoginModel 的模型刚刚更改。




如何实现:

  • 任何其他已经订阅此消息的视图模型将从服务中提取此更改的模型。 / p>


    1. 广播消息?

    2. 订阅邮件?


    解决方案

    您可以使用 MessageBus EventAggregator 通过使用弱引用向订阅者发布消息。看看我的实现(或 NuGet打包)。



    它还可以通过应用 HandleOnUIThreadAttribute Handle 方法。



    您的案例中的用法将如下所示:

      //消息
    public class LoginModelChanged
    {
    public LoginModelChanged(LoginModel model)
    {
    Model = model;
    }

    public LoginModel Model {get;私人集合
    }

    //发布消息的服务
    public class ModelProviderService
    {
    private IMessageBus _messageBus;
    私人LoginModel _loginModel;

    public ModelProviderService(IMessageBus messageBus)
    {
    _messageBus = messageBus;
    }

    public LoginModel LoginModel
    {
    get {return _loginModel; }
    set
    {
    _loginModel = value;
    _messageBus.Publish(new LoginModelChanged(value));
    }
    }
    }

    //订阅ViewModel
    public class SomeViewModel:IHandle< LoginModelChanged>
    {
    public SomeViewModel(IMessageBus messageBus)
    {
    messageBus.Subscribe(this);
    }

    public void Handle(LoginModelChanged message)
    {
    //做某事与message.Model
    }
    }

    如果你想更多地了解内部的工作原理以及如何实现这一点;查看 GitHub存储库中的源代码。随意使用代码,你喜欢:)


    I'm prototyping a WPF application with the MVVM pattern. Following an answer to this question I have set up a ModelProviderService which exposes models as properties. The consumers of the service are the viewmodels, i.e. they pull their models from the service instead of instantiating them theirselves.

    class ModelProviderService {
    
      private LoginModel loginModel;
      public LoginModel LoginModel {
        get { return loginModel; }
        set { loginModel = value; }
      }
    
      private ProjectsModel projectsModel;
      public ProjectsModel ProjectsModel {
        get { return projectsModel; }
        set { projectsModel = value; }
      }
    
      public ModelProviderService() {
        loginModel = new LoginModel();
        projectsModel = new ProjectsModel();
      }    
    }
    

    Now, here is what shall happen:

    • A viewmodel changes a property of e.g. the LoginModel property.
    • The viewmodel pushes the model property back to the service by setting its property: modelService.LoginModel.MyProperty = localLoginModel.MyProperty;
    • The service shall publish a message: "Hey, my model of type LoginModel just changed."
    • Any other viewmodel that has subscribed to this message will pull this changed model from the service.

    How can I implement:

    1. the "broadcast message"?
    2. the subscription to the message?

    解决方案

    You could use a MessageBus or EventAggregator to publish messages to subscribers by using weak references. Take a look at my implementation (or the NuGet packgage).

    It can also marshal the message handling to the UI thread for you (if you need to update UI components) by applying the HandleOnUIThreadAttribute on the Handle method.

    Usage in your case would be something like:

    // The message
    public class LoginModelChanged
    {
        public LoginModelChanged(LoginModel model)
        {
            Model = model;
        }
    
        public LoginModel Model { get; private set; }
    }
    
    // Service that publishes messages
    public class ModelProviderService
    {
        private IMessageBus _messageBus;
        private LoginModel _loginModel;
    
        public ModelProviderService(IMessageBus messageBus)
        {
            _messageBus = messageBus;
        }
    
        public LoginModel LoginModel
        {
            get { return _loginModel; }
            set
            {
                _loginModel = value;
                _messageBus.Publish(new LoginModelChanged(value));
            }
        }
    }
    
    // Subscribing ViewModel
    public class SomeViewModel : IHandle<LoginModelChanged>
    {
        public SomeViewModel(IMessageBus messageBus)
        {
            messageBus.Subscribe(this);
        }
    
        public void Handle(LoginModelChanged message)
        {
            // Do something with message.Model
        }
    }
    

    If you want to know more about the inner workings and how to implement this; Check out the source code in the GitHub repository. Feel free to use the code as you like :)

    这篇关于在C#中实现消息/订阅机制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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