How to populate Func <T> dictionary dynamically
Consider the following:
public interface ISomething
{
string Something();
}
public class A : ISomething
{
public string Something()
{
return "A";
}
}
public class B : ISomething
{
public string Something()
{
return "B";
}
}
public class Helper
{
private static readonly Dictionary<string, Func<string, string>> Actions =
new Dictionary<string, Func<string, string>>(StringComparer.OrdinalIgnoreCase);
public Helper()
{
Actions["A"] = DoSomething<A>;
Actions["B"] = DoSomething<B>;
var types = Assembly.GetExecutingAssembly().GetTypes().Where(t => t.GetInterfaces().Contains(typeof(ISomething)));
foreach (var type in types)
{
Console.WriteLine(type.Name);
// Actions[type.Name] = ????;
}
}
public static string DoSomething<T>(string data) where T : ISomething
{
T obj = JsonConvert.DeserializeObject<T>(data);
// Some manipulations
return obj.Something();
}
}
void Main()
{
var h = new Helper();
}
I can fill in the dictionary manually. However, is it possible to add it dynamically?
How can I convert a generic method to Func?
+4
1 answer
You can create Expressionand compile it in Func<string, string>:
public Helper()
{
var types = Assembly.GetExecutingAssembly().GetTypes().Where(t => t.GetInterfaces().Contains(typeof(ISomething)));
foreach (var type in types)
{
var data = Expression.Parameter(typeof(string), "data");
var call = Expression.Call(typeof(Helper), "DoSomething", new Type[] { type }, data);
var lambda = Expression.Lambda(call, data);
Actions[type.Name] = (Func<string, string>)lambda.Compile();
}
}
+4