I have a generic class that has a method ‘Call’ on it with a generic return type and a lambda expression as a parameter. This has to be generated with reflection, and since the types are unknown, I need to create the lambda expression the long way. I have a working solution listed below, but I do not like having to get the instance out of the generic class since it is private and does some logic on a retrieve.
Class:
public class Proxy<T>
{
public TR Call<TR>(Func<T, TR> serviceInvoke)
private T Instance
}
Reflection Usage:
var serviceInstance = proxy.GetType().GetProperty("Instance", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(proxy, null);
var serviceMethod = type.GetMethod(rule.ServiceMethodName);
var parameters = serviceMethod.GetParameters().Select(parameterInfo => PropertyChainNavigator.GetValueForPropertyChain(((string)rule.Parameters[parameterInfo.Name]).Split(new[] { '.' }), context)).ToArray();
var thisParam = Expression.Constant(serviceInstance);
var valueParams = parameters.Select(Expression.Constant).ToList();
var call = Expression.Call(thisParam, serviceMethod, valueParams);
var func = Expression.Lambda(call, Expression.Parameter(type)).Compile();
var callMethod = proxy.GetType().GetMethods().Where(x => x.Name == "Call" && x.ReturnType != typeof(void)).First().MakeGenericMethod(serviceMethod.ReturnType);
result = callMethod.Invoke(proxy, new[] { func });
Normal Usage:
var proxy = new Proxy<ITestClass>();
proxy.Call(x => x.Method);
I have tried to change the Expression.Call to not take an instance, but that only works on static methods. Does anyone know of a way for me to create the call, turn it into an lambda and have it compile without erroring
If you used lambda instead of expressions, your current code would look like this:
Note that the lambda takes the parameter
i, but doesn’t use it. I assume you want to call the method directly oni, i.e. something like this:To do that, use the value of
Expression.Parameter()asthisParam: