MethodAccessException using event aggregator in Silverlight

Topics: Prism v2 - Silverlight 2
May 25, 2009 at 10:45 AM

Hi all,

I encounter a problem using the event aggregator in silverlight. I get MethodAccessException when subscribing to an event. Here is my code :

 

EventAggregator EventService = new EventAggregator ();

<font size="2" color="#2b91af"><font size="2" color="#2b91af">

 

</font></font><font size="2" color="#2b91af">

 

</font>

EventService.GetEvent<GenericEvent<string>>().Subscribe(

s =>{if (s.Topic == "EventTopic" }

)

 

This is the stackTrace :

 at System.Delegate.BindToMethodInfo(Object target, RuntimeMethodHandle method, RuntimeTypeHandle methodType, DelegateBindingFlags flags)
   at System.Delegate.CreateDelegate(Type type, Object firstArgument, MethodInfo method, Boolean throwOnBindFailure)
   at System.Delegate.CreateDelegate(Type type, Object firstArgument, MethodInfo method)
   at Microsoft.Practices.Composite.Events.DelegateReference.TryGetDelegate()
   at Microsoft.Practices.Composite.Events.DelegateReference.get_Target()
   at Microsoft.Practices.Composite.Events.EventSubscription`1..ctor(IDelegateReference actionReference, IDelegateReference filterReference)
   at Microsoft.Practices.Composite.Presentation.Events.CompositePresentationEvent`1.Subscribe(Action`1 action, ThreadOption threadOption, Boolean keepSubscriberReferenceAlive, Predicate`1 filter)
   at Microsoft.Practices.Composite.Presentation.Events.CompositePresentationEvent`1.Subscribe(Action`1 action, ThreadOption threadOption, Boolean keepSubscriberReferenceAlive)
   at Microsoft.Practices.Composite.Presentation.Events.CompositePresentationEvent`1.Subscribe(Action`1 action, ThreadOption threadOption)
   at Microsoft.Practices.Composite.Presentation.Events.CompositePresentationEvent`1.Subscribe(Action`1 action)
   at MyEventAggregatorSeriveTest.SubscriberUserControl.UserControl_Loaded(Object sender, RoutedEventArgs e)

 

Any help.

Thanks...

 

 

May 26, 2009 at 8:37 PM

Hi wasimf,

 

The current version of silverlight (SL 2.0) does not support weak references to lambda expressions. Taken from the Prism-v2 documentation Event Aggregation QuickStart:

Silverlight does not support weak references to lambda expressions or anonymous delegates. Therefore, the filter parameter must be a separate method if you are targeting Silverlight.

 

To work around this issue, you could create a separate method to implement the filtering. For example:

EventService.GetEvent<GenericEvent<string>>().Subscribe(YourAction)

.....

public void YourAction(string topic)

{

   if(topic == "something")

   {

      // more code

   }

}

 

If you are using the if statement to filter which events to process, you could find useful the overload of the Subscribe method that accepts a filter.

 

Hope it helps!

 

Matias Bonaventura

http://blogs.southworks.net/matiasb

Jul 29, 2009 at 4:05 AM

Matias

but your sample code is not a *filter* method, it's a *action* method. Here is a correct sample from the document you referred to:

 

public bool FundOrderFilter(FundOrder fundOrder)
{
return fundOrder.CustomerId == _customerId;
}
...

FundAddedEvent fundAddedEvent = eventAggregator.GetEvent<FundAddedEvent>();

subscriptionToken = fundAddedEvent.Subscribe(FundAddedEventHandler, ThreadOption.UIThread, false, FundOrderFilter);
Dec 20, 2009 at 1:51 AM
matiasbonaventura wrote:

Hi wasimf,

 

The current version of silverlight (SL 2.0) does not support weak references to lambda expressions. Taken from the Prism-v2 documentation Event Aggregation QuickStart:

Silverlight does not support weak references to lambda expressions or anonymous delegates. Therefore, the filter parameter must be a separate method if you are targeting Silverlight.

 

Hi matiasbonaventura,

Your solution is right, but the reason is not correct. I think this is the true reason: http://msdn.microsoft.com/en-us/library/74x8f551%28VS.96%29.aspx
        In Silverlight, method must specify an accessible method.

Lambda and anonymous delegates are implemented as private methods, so they cannot be accessed.

Feb 7, 2011 at 1:20 PM

You can work around this issue by wrapping the target method in a method which is accessible publicly.

An example of this can be found here:

http://peplowdown.wordpress.com/2011/02/07/compositepresentationevent-methodaccessexception-keep-your-privates-to-yourself/

 

Oct 31, 2011 at 4:42 PM
Edited Oct 31, 2011 at 4:42 PM

It's unfortunate that Silverlight works this way. It's been two releases of Prism and still no acceptable workaround.

Being unable to use an anonymous lambda or private method forces one to break best practices (encapsulation), and fatten a public interface on a class just so messages can be passed.

This issue has been most frustrating, and the workaround is nearly unacceptable.

Developer
Oct 31, 2011 at 5:38 PM

Hi,

Please take into account that, if you set the keepSubscriberReferenceAlive parameter in the Subscribe method to true, you will be able to pass a private method (such as a lambda expression) as the handler for the event subscription.

You could, anyway, create a work item in the issue tracker so that the Prism team takes this into account for future releases of Prism.

I hope you find this helpful.

Guido Leandro Maliandi 
http://blogs.southworks.net/gmaliandi