Search code examples
c#wpfmvvmprismeventaggregator

Prism EventAggregator. Receive the event and send it again


In my project I have three ViewModels (for example, ViewModelA, ViewModelB and ViewModelC).
I need to write the following logic.
The ViewModelA sends the value to ViewModelB using the EventAggregator from Prism.
The ViewModelB receives the value and sends it to ViewModelC.
The ViewModelC receives the value and doing something.

Here is the code:

// The data that will be send using the event aggregator.
class EventData : PubSubEvent<int>
{ 
}

class ViewModelA
{
    IEventAggregator m_eventAggregator;

    public ViewModelA(IEventAggregator eventAggregator)
    {
        m_eventAggregator = eventAggregator;

        // Publish some value.
        eventAggregator.GetEvent<EventData>().Publish(10);
    }
}

class ViewModelB
{
    IEventAggregator m_eventAggregator;

    public ViewModelB(IEventAggregator eventAggregator)
    {
        m_eventAggregator = eventAggregator;

        eventAggregator.GetEvent<EventData>().Subscribe(OnDataReceived);
    }

    void OnDataReceived(int value)
    {
        // Here I want to send the value to the ViewModelC. How can I do it?
    }
}

PS: it is the part of the big project. So, please don’t suggest sending from ViewModelA to ViewModelC directly, without the ViewModelB.


Solution

  • The event aggregator works in a way that everybody can listen to every event. So, if you want to send from A to B (and then from B to C), you need two distinct "private" events.

    A:

     eventAggregator.Publish<AtoB>( value );
    

    B:

     eventAggregator.Subscribe<AtoB>( x => {
                                               var y = process(x);
                                               eventAggregator.Publish<BtoC>( y );
                                           } );
    

    C:

     eventAggregator.Subscribe<BtoC>( x => whatever( x ) );
    

    Side-note: what you publish and subscribe is the event type, not the payload type. The naming of your event (EventData) is a bit awkward, because one will confuse it with the payload. A better name would be DataEvent... or, here, RawDataEvent and ProcessedDataEvent.

    Side-note 2: obviously, the event aggregator is not intended for non-broadcast messages. You can force it (either using distinct event types or, for example, by including a destination-id in the payload), but I'd prefer a messaging system that's designed for point-to-point messages.