Search code examples
c#wpfmvvmprismeventaggregator

Prism WPF Event Aggregator Event Class Alternative


I am working on a project with over 30 properties that are constantly being updated using data binding. The way i'm fetching the new values sent by the server is with event aggregator, which updates the properties. So far, here's how I got it working

Event Class

public class Zone1TempEvent : PubSubEvent<int>
{           
}

Property

private int _zone1Temp;

public int Zone1Temp
{
   get { return _zone1Temp; }
   set { SetProperty(ref _zone1Temp, value); }     
}

Subscribe

eventAggregator.GetEvent<Zone1TempEvent>().Subscribe(tempZone1Update);

Method

private void tempZone1Update(int value) { Zone1Temp = value; }

Publish

 private void checkResponsability(ItemValueCallback itemValue)
        {
            switch ((string)itemValue.ClientHandle)
            {
                case "Zone1_Temp":
                    int Zone1Temp = Int32.Parse((string)itemValue.Value);
                    _eventAggregator.GetEvent<Zone1TempEvent>().Publish(Zone1Temp);
                    break;
            }
        }

However, I can't imagine doing this 30 times. I am looking for an alternative. I would like to avoid having to create a class for each event, as well as a method for each property. Is it possible to have one generic class called UpdatePropertyEvent, and use this to do so. Or maybe do something inspired by this thread with enums? Mixing enums with event classes in an event aggregator Thanks


Solution

  • Instead of using the EventAggregator, your service can implement IPropertyChanged (and the models returned from the service can, depending on your scenario ). This way you have to react to just one event.

    Also, you could just publish a single event that carries the two string values, like class ServerUpdatedEvent : PubSubEvent<PropertyValuePair> and do the parsing and distributing to properties in the view model.

    Example:

        // ...service...
        private void checkResponsability(ItemValueCallback itemValue)
        {
            _eventAggregator.GetEvent<ServerUpdatedEvent>().Publish(new PropertyValuePair((string)itemValue.ClientHandle,(string)itemValue.Value);
        }
    
        // ...view model or intermediate service...
        private void OnServerUpdate(PropertyValuePair data)
        {
            switch (data.Property)
            {
                case "Zone1_Temp": Zone1Temp = int.Parse(data.Value); break;
            }
        }
    

    If your properties can be named like the events or you put attributes on them, you can use reflection to find the property for an incoming event. Reflection is slow, though, so that if you have lots of events, you might need some type of caching.

    Something like this could work for you, too.