3

recently I was trying to do something like this in WP7 app

I have class

abstract class A {
//this method has an implementation
protected void DoSomething<T, TKey>(Func<T, TKey> func) { //impl here }
};

and I want to invoke that protected method via reflection in derived class:

    public class B : A {
      void SomeMethod(Type tableType, PropertyInfo keyProperty){ 
        MethodInfo mi = this.GetType()
                .GetMethod("DoSomething", BindingFlags.Instance | BindingFlags.NonPublic)
                .MakeGenericMethod(new Type[] { tableType, keyProperty.GetType() });

            LambdaExpression lambda = BuildFuncExpression(tableType, keyProperty);
// MethodAccessException
            mi.Invoke(this, new object[] { lambda });
        }

        private System.Linq.Expressions.LambdaExpression BuildFuncExpression(Type paramType, PropertyInfo keyProperty)
        {
            ParameterExpression parameter = System.Linq.Expressions.Expression.Parameter(paramType, "x");
            MemberExpression member = System.Linq.Expressions.Expression.Property(parameter, keyProperty);
            return System.Linq.Expressions.Expression.Lambda(member, parameter);
        }


}
    };

and I'm getting MethodAccessException. I understand this is a security exception but I'm able to call the method normally from that place, so I should be able to call it via reflection as well.

What might be wrong? Thanks!

AnthonyWJones
  • 187,081
  • 35
  • 232
  • 306
Robert
  • 3,276
  • 1
  • 17
  • 26
  • 3
    Why do you want to do it via reflection, rather than just compiling the call in? – Rowland Shaw Mar 10 '11 at 08:59
  • Seriously, why do you want to do it via reflection, when all it adds is a bunch of overhead? – Massif Mar 10 '11 at 09:03
  • Hi, thanks for comments, this code is related to Sterling DB. I want to have attributes which indicate Sterling table (class level) and table key (property level). Then I want to gather all classes with this attribute and register them as tables via Sterling API. The reason I use reflection is that the type of generic method arguments of CreateTableDefinition used for registration, is not known and can be anything. In addition there is a lambda which says which property is the key. The CreateTableDefinition is in class A in this case. – Robert Mar 10 '11 at 13:06

1 Answers1

4

From http://msdn.microsoft.com/en-us/library/system.methodaccessexception.aspx

This exception is thrown in situations such as the following:

  • A private, protected, or internal method that would not be accessible from normal compiled code is accessed from partially trusted code by using reflection.

  • A security-critical method is accessed from transparent code.

  • The access level of a method in a class library has changed, and one or more assemblies that reference the library have not been recompiled.

Within WP7, I think the problem is most likely to be that this reflection code attempts to access private (NonPublic) methods - and WP7 has been very clear that it is locked down to prevent this type of access.

Stuart
  • 66,722
  • 7
  • 114
  • 165
  • Thanks, the thing is, that the method is accessible when hardcoded and compiled. I'm thinking about compiling the library I'm using (Sterling DB) with assembly: AllowPartiallyTrustedCallers – Robert Mar 10 '11 at 13:13
  • I think its the methods in the reflection assembly that aren't trusted - so there won't be a way around this. – Stuart Mar 10 '11 at 13:26
  • In case the didn't make sense - I think that the problem here is not access to the reflected methods, but is instead access to this bit of the Reflection mechanism - WP7 is locked down to prevent you from using it on e.g. undocumented APIs – Stuart Mar 10 '11 at 13:45
  • comming back to this, tried to add the source code to the solution as another project, but no luck. Seems it is not possible. Thanks. – Robert Mar 15 '11 at 19:21
  • LOL - I'm currently trying to write the same sort of code... and I hit the same exception... and I searched for an answer... and I found my own answer... ah well :) – Stuart Sep 23 '11 at 09:40
  • yep. in wp7 only public-reflection is possible. all other access is simply denied. anyways, if they wanted to lock down the undocumented APIs, they have failed, just look at xda forums.. I can only suppose the lock is there because the apps are meant to run in "sandbox" and to "not be able to get out". with private reflection, it would be dead easy to get in many places considered 'outside'. – quetzalcoatl Apr 11 '12 at 12:36
  • True about the xda forums. But the Apis are locked down for apps in the marketplace as a result of this. And the xda people will always find a way - those guys cook up all sorts of amazing things. – Stuart Apr 11 '12 at 21:25