这可以通过像这样深入LambdaExpression 来实现:
string GetMethodCallName(LambdaExpression expression)
{
var unary = (UnaryExpression)expression.Body;
var methodCall = (MethodCallExpression)unary.Operand;
var constant = (ConstantExpression)methodCall.Object;
var memberInfo = (MemberInfo)constant.Value;
return memberInfo.Name;
}
不幸的是,GetMethodCallName 不能用你想要的 x => x.GetRoles 语法直接调用,因为没有类型参数来定义 x 是什么。这意味着您需要为Action 和Func 支持的每个输入参数数量创建AddMethod 的重载:
void AddMethod<T>(Expression<Func<T, Action>> expression);
void AddMethod<T, Arg1>(Expression<Func<T, Action<Arg1>>> expression);
void AddMethod<T, Arg1, Arg2>(Expression<Func<T, Action<Arg1, Arg2>>> expression);
void AddMethod<T, TResult>(Expression<Func<T, Func<TResult>>> expression);
void AddMethod<T, Arg1, TResult>(Expression<Func<T, Func<Arg1, TResult>>> expression);
void AddMethod<T, Arg1, Arg2, TResult>(Expression<Func<T, Func<Arg1, Arg2, TResult>>> expression);
然后在每个AddMethod 实现中调用GetMethodCallName 并带有表达式参数:
void AddMethod<T, Arg1>(Expression<Func<T, Action<Arg1>>> expression)
{
var methodName = GetMethodCallName(expression);
}
然后可以调用AddMethod,指定方法的包含类型和返回输入类型:
.AddMethod<IRoleService>(x => x.GetRoles);
.AddMethod<IRoleService, TResult>(x => x.GetRoles);
.AddMethod<IRoleService, Arg1, TResult>(x => x.GetRoles);
地点:
-
TResult 是 .GetRoles 的返回类型
-
Arg1 是.GetRoles 的第一个参数的类型