Je transfère une bibliothèque de classes existante à Silverlight. J'ai beaucoup utilisé la compilation d'expressions lambda et maintenant je rencontre des problèmes de sécurité à cause de cela.Sécurité Silverlight: octroi d'une autorisation d'accès aux classes anonymes à une bibliothèque de classes
En particulier, si une classe anonyme à partir d'une application client SL participe à une expression lambda, je ne peux pas le compiler: je reçois un MethodAccessException
avec la trace de pile suivante:
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)
J'ai essayé d'utiliser InternalsVisibleTo
dans l'application SL client pour exposer les classes anonymes à ma bibliothèque de classe, mais cela n'a pas aidé. En fait, ça devrait aider, mais je ne comprends pas pourquoi ça ne marche pas.
Des idées?
MISE À JOUR:
J'ai compris que le problème n'est pas dans les expressions lambda, mais dans l'invocation de méthode générique dynamique:
Si nous avons le code suivant dans une bibliothèque de classes:
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
}
}
et nous appelons la méthode StaticReceive de l'application comme ceci:
class InternalClass { }
void MethodInUserApp()
{
var x = new InternalClass();
LibClass.StaticReceive(x);
}
cela fonctionne bien, mais si nous utilisons DynamicReceive
, il échoue. Il semble que CLR considère le paramètre x
dans la méthode Process
à partir du type InternalClass
, non générique T
, et puisque InternalClass
n'est pas accessible pour la bibliothèque, interdit son invocation.
Cela ressemble à un bug, non?