I'm porting an existing class library to Silverlight. I used lambda expression compilation a lot and now I'm experiencing security problems because of it.
In particular, if an anonymous class from a client SL app is participating in a lambda expression, I cannot compile it: I get a MethodAccessException
with the following stack trace:
MethodBase.PerformSecurityCheck(Object obj, RuntimeMethodHandle method, IntPtr parent, UInt32 invocationFlags)
RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
MethodBase.Invoke(Object obj, Object[] parameters)
Expression.Lambda(Type delegateType, Expression body, IEnumerable<T> parameters)
Expression.Lambda(Type delegateType, Expression body, ParameterExpression[] parameters)
Expression.Lambda(Expression body, ParameterExpression[] parameters)
I tried to use InternalsVisibleTo
in the client SL app to expose anonymous classes to my class library, but it didn't help. Actually it should help, but I cannot understand why it does not.
Any ideas?
UPDATE:
I've figured out that the problem is not in lambda expressions, but in dynamic generic method invocation:
If we have the following code in a class library:
public class LibClass
{
public static void StaticReceive<T>(T x)
{
Process<T>(x);
}
public static void DynamicReceive(object x)
{
typeof(LibClass).GetMethod("Process", BindingFlags.NonPublic | BindingFlags.Static)
.MakeGenericMethod(x.GetType())
.Invoke(null, new object[] { x });
}
static void Process<T>(T x)
{
// some work with typed x
}
}
and we call the StaticReceive method from the app like this:
class InternalClass { }
void MethodInUserApp()
{
var x = new InternalClass();
LibClass.StaticReceive(x);
}
it works OK, but if we use DynamicReceive
, it fails. It looks like CLR considers the x
parameter in the Process
method as of type InternalClass
, not generic T
, and since InternalClass
is not accessible for the library, forbids its invocation.
It looks like a bug, no?