Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to return data from a subscribed method using EventAggregator and Microsoft Prism libraries

I am working on a WPF project, using MVVM and Microsoft Prism libraries. So, when I need to communicate through classes I use the class Microsoft.Practices.Prism.MefExtensions.Events.MefEventAggregator and I publish events and subscribe methods as below:

To publish:

myEventAggregator.GetEvent<MyEvent>().Publish(myParams)

To Subscribe:

myEventAggregator.GetEvent<MyEvent>().Subscribe(MySubscribedMethod)

But my question is: Is there a way to return some data from the "Subscribed method" after publishing an event??

like image 345
Dante Avatar asked Jun 28 '12 22:06

Dante


1 Answers

As far as I know, if all the event subscribers are using the ThreadOption.PublisherThread option (which is also the default), the event is performed synchronously and the subscribers can modify the EventArgs object, so you could have in the publisher

myEventAggregator.GetEvent<MyEvent>().Publish(myParams)
if (myParams.MyProperty)
{
   // Do something
}

The subscriber code would look like this:

// Either of these is fine.
myEventAggregator.GetEvent<MyEvent>().Subscribe(MySubscribedMethod)
myEventAggregator.GetEvent<MyEvent>().Subscribe(MySubscribedMethod, ThreadOption.PublisherThread)

private void MySubscribedMethod(MyEventArgs e)
{
    // Modify event args
    e.MyProperty = true;
}

If you know that the event should always be called synchronously, you can create your own base class for events (instead of CompositePresentationEvent<T>) which overrides the Subscribe method, and only allow subscribers to use the ThreadOption.PublisherThread option. It would look something like this:

public class SynchronousEvent<TPayload> : CompositePresentationEvent<TPayload>
{
    public override SubscriptionToken Subscribe(Action<TPayload> action, ThreadOption threadOption, bool keepSubscriberReferenceAlive, Predicate<TPayload> filter)
    {
        // Don't allow subscribers to use any option other than the PublisherThread option.
        if (threadOption != ThreadOption.PublisherThread)
        {
            throw new InvalidOperationException();
        }

        // Perform the subscription.
        return base.Subscribe(action, threadOption, keepSubscriberReferenceAlive, filter);
    }
}

then instead of deriving MyEvent from CompositePresentationEvent, you derive it from SynchronousEvent, which will guarantee you that the event will be called synchronously and that you will get the modified EventArgs.

like image 179
Adi Lester Avatar answered Nov 01 '22 12:11

Adi Lester