使用Expressions调用实体的方法

  Expressions如何实现反射调用实现方法类似的功能呢(并且效率比使用反射高)?下面就把方法分享给大家:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Linq.Expressions;
 5 using System.Reflection;
 6 using System.Text;
 7 using System.Threading.Tasks;
 8 
 9 namespace Syspetro.Core.Extensions
10 {
11     public class DynamicMethodExecutor
12     {
13         private readonly Func<object, object[], object> m_execute;
14 
15         public DynamicMethodExecutor(object obj, string method)
16         {
17             MethodInfo methodInfo = obj.GetType().GetMethod(method);
18             this.m_execute = GetExecuteDelegate(methodInfo);
19         }
20 
21         public DynamicMethodExecutor(MethodInfo methodInfo)
22         {
23             this.m_execute = GetExecuteDelegate(methodInfo);
24         }
25         /// <summary>
26         /// 调用方法
27         /// </summary>
28         /// <param name="instance">实体对象</param>
29         /// <param name="parameters">参数列表</param>
30         /// <returns></returns>
31         public object Execute(object instance, object[] parameters)
32         {
33             return this.m_execute(instance, parameters);
34         }
35         private static Func<object, object[], object> GetExecuteDelegate(MethodInfo methodInfo)
36         {
37             // parameters to execute
38             ParameterExpression instanceParameter =
39                 Expression.Parameter(typeof(object), "instance");
40             ParameterExpression parametersParameter =
41                 Expression.Parameter(typeof(object[]), "parameters");
42 
43             // build parameter list
44             List<Expression> parameterExpressions = new List<Expression>();
45             ParameterInfo[] paramInfos = methodInfo.GetParameters();
46             for (int i = 0; i < paramInfos.Length; i++)
47             {
48                 // (Ti)parameters[i]
49                 BinaryExpression valueObj = Expression.ArrayIndex(
50                     parametersParameter, Expression.Constant(i));
51                 UnaryExpression valueCast = Expression.Convert(
52                     valueObj, paramInfos[i].ParameterType);
53 
54                 parameterExpressions.Add(valueCast);
55             }
56 
57             // non-instance for static method, or ((TInstance)instance)
58             Expression instanceCast = methodInfo.IsStatic ? null :
59                 Expression.Convert(instanceParameter, methodInfo.ReflectedType);
60 
61             // static invoke or ((TInstance)instance).Method
62             MethodCallExpression methodCall = Expression.Call(
63                 instanceCast, methodInfo, parameterExpressions);
64 
65             // ((TInstance)instance).Method((T0)parameters[0], (T1)parameters[1], ...)
66             if (methodCall.Type == typeof(void))
67             {
68                 Expression<Action<object, object[]>> lambda =
69                     Expression.Lambda<Action<object, object[]>>(
70                         methodCall, instanceParameter, parametersParameter);
71 
72                 Action<object, object[]> execute = lambda.Compile();
73                 return (instance, parameters) =>
74                 {
75                     execute(instance, parameters);
76                     return null;
77                 };
78             }
79             else
80             {
81                 UnaryExpression castMethodCall = Expression.Convert(
82                     methodCall, typeof(object));
83                 Expression<Func<object, object[], object>> lambda =
84                     Expression.Lambda<Func<object, object[], object>>(
85                         castMethodCall, instanceParameter, parametersParameter);
86 
87                 return lambda.Compile();
88             }
89         }
90     }
91 }

如何使用呢:

1 var service = _serviceProvider.GetService(type);//通过依赖注入实例化实体
2 
3 DynamicMethodExecutor dynamicMethodRun = new DynamicMethodExecutor(service, "Run");//调用实体类的 Run()方法
4 var redata = dynamicMethodRun.Execute(service, null);//redata为方法的返回值

 

posted @ 2021-03-10 23:50  听枫xl  阅读(328)  评论(0编辑  收藏  举报