I am trying to build a system that loads function delegates to a dictionary and then they can be called from anywhere in the environment asking the dictionary for the delegate.
My functions are of a format Func<string, string>
.
My code is
var methods = typeof(Keywords)
.GetMethods()
.Where(mt => mt.GetCustomAttributes(typeof(KDTAttribute), false).Count() > 0);
foreach (var method in methods)
{
string key = ((KDTAttribute)method.GetCustomAttributes(typeof(KDTAttribute), false)[0]).Keyword;
var combinedArgumentsExp = new Expression[] { Expression.Parameter(typeof(string),"param") };
var mtCall = Expression.Call(Expression.Constant(me), method,combinedArgumentsExp);
ParameterExpression targetExpr = Expression.Parameter(typeof(string), "param");
Func<string, string> result = Expression.Lambda<Func<string, string>>(mtCall, targetExpr).Compile();
retVal.Add(key, result);
}
I get the exception on the Expression.Lambda
line :
variable 'param' of type 'System.String' referenced from scope '', but it is not defined.
P.S:
If there is a better way to load delegates to a dictionary at run time I'll be happy for any suggestions.
You're calling Expression.Parameter
twice, which gives you different expressions. Don't do that - just call it once, and use that ParameterExpression
both places you need it:
var parameter = Expression.Parameter(typeof(string),"param");
string key = ((KDTAttribute)method.GetCustomAttributes(typeof(KDTAttribute), false)[0]).Keyword;
var mtCall = Expression.Call(Expression.Constant(me), method, parameter);
var result = Expression.Lambda<Func<string, string>>(mtCall, parameter).Compile();
See more on this question at Stackoverflow