Question

I am trying to get my IEventAggregator to allow me to publish and event in one module and catch it in another. I have tried my code below in a single module/project and it works great. It only fails when I have one module/project publish the event and another subscribe to it.

I have having my IEventAggregator injected into both modules via unity.

I have 3 projects, two of them have modules (call them A and B) and one is just a plain class library (call it Interfaces)

In class library Interfaces there is this code:

public class RandomTestEvent : CompositePresentationEvent<string>
{
}

In module A there is this code in a button click command (this is really in a View Model in the project):

var evt2 = _eventAggregator.GetEvent<RandomTestEvent>();
evt2.Publish("Testing");

In module B there is this code:

    public void Initialize()
    {
        var evt2 = _eventAggregator.GetEvent<RandomTestEvent>();
        evt2.Subscribe(OnRandomThingDone);
    }

    private void OnRandomThingDone(string obj)
    {
        MessageBox.Show("Random Event Done With: " + obj);            
    }

I can trace through and I see Subscribe get called. When I look at Publish geting called the debugger says Subscriptions = 1 (so it knows that the subscription was made, so I don't seem to have 2 different instances of IEventAggregator.)

But OnRandomThingDone never gets called after Publish.

Any Ideas why? (Do I need to post more code? If so let me know.)

Was it helpful?

Solution

Really random guess - your subscriber is getting GC'd before the event is published - since the default behavior of Prism's CompositePresentationEvent is to use WeakReferences for preserving subscriber target references.

So...try calling the Subscribe overload which allows you to specify keepSubscriberReferenceAlive and pass in true.

If your subscriber then receives the event successfully, it means that your class which contains OnRandomThingDone is going out of scope and getting GC'd before the event is published.

Random API reference: http://msdn.microsoft.com/en-us/library/ff921122(PandP.20).aspx

OTHER TIPS

Actually grimcoder is correct, a weak reference requires a public Action method. Utilizing a week reference relieves the coder of unsubscribing to the event, this is managed by the GC.

You can however use a strong reference by passing true to keepSubscriberReferenceAlive, which also can speed up your program if a large number of events is called in a short period of time.

For more information on this see: Chapter 9: Communicating Between Loosely Coupled Components Section Subscribing Using Strong References

It has nothing to do with GC since once Subsriber is attached reference to it never dies. The real problem is due to inaccessibility of the OnRandomThingDone if MUST be public i.e:

**public** void OnRandomThingDone(string obj)
{
    MessageBox.Show("Random Event Done With: " + obj);            
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top