如何使用EventAggregator和Microsoft Prism库从订阅方法返回数据

时间:2021-05-19 00:08:33

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:

我正在使用MVVM和Microsoft Prism库来开发WPF项目。所以,当我需要通过类进行通信时,我使用类Microsoft.Practices.Prism.MefExtensions.Events.MefEventAggregator,我发布事件和订阅方法如下:

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??

但我的问题是:有没有办法在发布事件后从“订阅方法”返回一些数据?

1 个解决方案

#1


12  

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

据我所知,如果所有事件订阅者都使用ThreadOption.PublisherThread选项(这也是默认选项),则事件将同步执行,订阅者可以修改EventArgs对象,因此您可以在发布者中使用

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:

如果您知道应始终同步调用该事件,则可以为事件创建自己的基类(而不是CompositePresentationEvent ),这将覆盖Subscribe方法,并且只允许订阅者使用ThreadOption.PublisherThread选项。它看起来像这样:

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.

然后,您不是从CompositePresentationEvent派生MyEvent,而是从SynchronousEvent派生它,它将保证您将同步调用该事件,并且您将获得修改后的EventArgs。

#1


12  

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

据我所知,如果所有事件订阅者都使用ThreadOption.PublisherThread选项(这也是默认选项),则事件将同步执行,订阅者可以修改EventArgs对象,因此您可以在发布者中使用

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:

如果您知道应始终同步调用该事件,则可以为事件创建自己的基类(而不是CompositePresentationEvent ),这将覆盖Subscribe方法,并且只允许订阅者使用ThreadOption.PublisherThread选项。它看起来像这样:

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.

然后,您不是从CompositePresentationEvent派生MyEvent,而是从SynchronousEvent派生它,它将保证您将同步调用该事件,并且您将获得修改后的EventArgs。