I'm using IronPython and I know how to expose methods from my class to the script's scope:
m_scope.SetVariable("log", new Action<string>(Log));
public void Log(string a)
{
Console.WriteLine(a);
}
However, instead of calling SetVariable
everytime I want to speed up the process using reflection. So, I created an attribute called ScriptMethodAttribute
:
public sealed class ScriptMethodAttribute : Attribute
{
public string Name { get; private set; }
public ScriptMethodAttribute(string name)
{
Name = name;
}
}
That way, I can define methods inside my class for the script to use, like so:
[ScriptMethod("log")]
public void Log(string a)
{
Console.WriteLine(a);
}
Now I want to call SetVariable on every method that uses this attribute to speed up the process. However, that doesn't seem to work.
This is a utility method that returns a list of Tuple<ScriptMethodAttribute, MethodInfo
.
public static IEnumerable<Tuple<TAttribute, MethodInfo>> FindMethodsByAttribute<TAttribute>()
where TAttribute : Attribute
{
return (from method in AppDomain.CurrentDomain.GetAssemblies()
.Where(assembly => !assembly.GlobalAssemblyCache)
.SelectMany(assembly => assembly.GetTypes())
.SelectMany(type => type.GetMethods())
let attribute = Attribute.GetCustomAttribute(method, typeof(TAttribute), false) as TAttribute
where attribute != null
select new Tuple<TAttribute, MethodInfo>(attribute, method));
}
This is located in my script's class constructor:
foreach (var a in Reflector.FindMethodsByAttribute<ScriptMethodAttribute>())
{
Action action = (Action)Delegate.CreateDelegate(typeof(Action), this, a.Item2);
m_scope.SetVariable(a.Item1.Name, action);
}
I'm receiving the following exception:
System.ArgumentException: Cannot bind to the target method because its signature or security transparency is not compatible with that of the delegate type.
I'm guessing it's because I have to include the required types in the Action constructor, but I don't know how to get them from the MethodInfo
class.
Aucun commentaire:
Enregistrer un commentaire