VB code needed: for EventAggregator subscribe

Topics: Prism v4 - Silverlight 4
Aug 16, 2011 at 10:19 PM

Hi all,

Somehow I cannot get this working: I would like one MEF module publish events and another MEF module subcribing to that event. I have based my code on the Prism templates. But I can't get the subscriber to respond to published events.

Here's the code I have so far: The publisher part

   _EventAggregator.GetEvent(Of PersonSelected)().Publish(Person))

The subscriber part:

_EventAggregator.GetEvent(Of PersonSelected)().Subscribe(New Action(Of Person)(AddressOf HandlePersonChanged), True)

And the handler code:

    Private Shared Sub HandlePersonChanged(ByVal obj As Person)
        'code to handle the Person object'
        MessageBox.Show(obj.ID)
    End Sub

The subscriber, as said before, won't respond. What am I missing here?

Developer
Aug 17, 2011 at 8:24 PM

Hi Peter,

You could try declaring your handler HandlePersonChanged as Public. This is a common issue when using Silverlight.
Also note that you must be careful with the timing. Make sure that you had already subscribed to your event at the moment you published it.
If you still can't find a solution to your problem, it would be helpful if you could provide us with a repro sample application, so that we can help you further with this.

I hope you find this useful.

Agustin Adami
http://blogs.southworks.net/aadami

Aug 17, 2011 at 9:15 PM
Edited Aug 17, 2011 at 9:17 PM

HI Aadami,

Thanks for your reply, but unfortunately the "Public" suggestion you give does not help. I had tried this before. Assembling a concise version of my project will take some time, so a couple of days I guess. Bare with me...

 

In the mean time, I have been studying the bootstrapper again, the issue might come from there. What is the correct statement to initialize an EventAggregator in the (MEF) bootstrapper?

Regards,

Peter

Developer
Aug 18, 2011 at 2:18 PM

Peter,

You can find how the EventAggregator is made available to the container when using MEF in the MefEventAggregator class, which can be found in the Events folder in the Prism.MefExtensions project. You can check the content of that class below:

[Export(typeof(IEventAggregator))]
    public class MefEventAggregator : EventAggregator
    {    }

This exports the default implementation of the EventAggregator using the IEventAggregator interface as the contract, so as to enable to you access the event aggregator service through that interface.

Also you might find the following thread very useful where this topic is covered.

I hope you find this helpful.

Agustin Adami
http://blogs.southworks.net/aadami

Aug 22, 2011 at 1:52 PM

@ Aadami,

I'm still in the dark... I can see in the Container of my application that there is a MEFEventAggregator allright. But how do I inject that into a module, while that module is in a separate project? If I use this statement:

  <ImportingConstructor()>
    Public Sub New(ByVal par_EventAggregator As IEventAggregator)

then I get an error message that there is no parameterless constructor for the module. Now what?

 

Developer
Aug 23, 2011 at 2:11 PM

Hi,
It would be helpful if you could provide us with a repro sample application that portrays that behavior.

Regards,

Agustin Adami
http://blogs.southworks.net/aadami

Aug 24, 2011 at 6:09 PM

HI Aadami,

In the mean time I have found a workaround. The cause of my problem appeared to be the following:

1. I instantiate a View via a separate Init process (like in the MEF template projects in Visual Studio)

   Public Sub Initialize() Implements IModule.Initialize
        _regionManager.RegisterViewWithRegion(strRegionName, Function() _serviceLocator.GetInstance(Of PersonBannerView)())
    End Sub

2. in the XAML code for the View I refer to the ViewModel in order to use it's properties, so the View instantiates it's related ViewModel, without any parameters

<UserControl.Resources>
        <ViewModel:PersonBannerViewModel x:Key="MyViewModel"/>
</UserControl.Resources>

3 the constructor of the ViewModel is like I showed in my previous message, so with the IEventAggregator. That constructor does have one parameter, so causes the error message.

    <ImportingConstructor()> _
    Public Sub New(ByVal eventAggregator As IEventAggregator)
                m_eventAggregator = eventAggregator
    End Sub

The workaround I have found is that I instantiate the ViewModel from the View's code-behind instead, where it can be done without the parameter-confusion. What I miss in this construction is the advantage of being able to get to the properties of the ViewModel.  I cannot set the ViewModel in the UserControl.Resources and hence not refer to it as a StaticResource. If you have a better suggestion, please come up with it. I keep the feeling that I have lost some advantages of MVVM I used to have before.

Peter

Developer
Aug 24, 2011 at 7:06 PM

Hi Peter,

I'm glad you've found the solution to your problem; thank you for sharing it with the rest of the community.

Best regards,

Agustin Adami
http://blogs.southworks.net/aadami