Implementing a message/subscription mechanism in C#

空扰寡人 提交于 2019-12-20 13:54:17

问题


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?

回答1:


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 :)




回答2:


If you want to distribute messages inside a WPF application, you may go with EventAggregator of prism framework.

EventAggregator allows viewmodels to weakly subsribe to events, requiring no knowledge about the sender. This allows you to easily distribute messages accross components or modules.



来源:https://stackoverflow.com/questions/14395442/implementing-a-message-subscription-mechanism-in-c-sharp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!