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, Expres开发者_如何学Csion 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?
Solved: Add the following code to your AssemblyInfo.cs:
[assembly: InternalsVisibleTo("System.Core, PublicKey=" +
"00240000048000009400000006020000002400005253413100040000010001008d56c76f9e8649" +
"383049f383c44be0ec204181822a6c31cf5eb7ef486944d032188ea1d3920763712ccb12d75fb7" +
"7e9811149e6148e5d32fbaab37611c1878ddc19e20ef135d0cb2cff2bfec3d115810c3d9069638" +
"fe4be215dbf795861920e5ab6f7db2e2ceef136ac23d5dd2bf031700aec232f6c6b1c785b4305c" +
"123b37ab")]
Discussed in the Silverlight forum
精彩评论