MethodProxy.cs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Reflection;
  6. using System.Linq.Expressions;
  7. namespace FWindSoft
  8. {
  9. public sealed class MethodProxy
  10. {
  11. public T Proxy<T>(T t)
  12. {
  13. var primitive = t as Delegate;
  14. if (primitive == null)
  15. return t;
  16. MethodInfo method = primitive.Method;
  17. var parameters = method.GetParameters();
  18. List<ParameterExpression> listParameters = new List<ParameterExpression>();
  19. foreach (var item in parameters)
  20. {
  21. listParameters.Add(Expression.Parameter(item.ParameterType));
  22. }
  23. MethodInfo preMethod = (this.GetType()).GetMethod("Pre", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
  24. MethodInfo postMethod = (this.GetType()).GetMethod("Post", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
  25. var pre = Expression.Call(Expression.Constant(this), preMethod);
  26. var post = Expression.Call(Expression.Constant(this), postMethod);
  27. Expression instance = primitive.Target != null ? Expression.Constant(primitive.Target, primitive.Target.GetType()) : null;
  28. MethodCallExpression execute = Expression.Call(instance, method, listParameters.ToArray());
  29. bool hasReturn = method.ReturnType != typeof(void);
  30. BlockExpression block = null;
  31. if (hasReturn)
  32. {
  33. #region 有返回值处理
  34. LabelTarget lblTarget = Expression.Label(method.ReturnType, "return");
  35. ParameterExpression resultTemp = Expression.Parameter(method.ReturnType);
  36. BinaryExpression assigment = Expression.Assign(resultTemp, execute);
  37. GotoExpression returnEx = Expression.Return(lblTarget, resultTemp);
  38. object defualtValue = method.ReturnType.IsValueType ? Activator.CreateInstance(method.ReturnType) : null;
  39. //标签表达式写在最后,则捕获返回值
  40. LabelExpression lblEx = Expression.Label(lblTarget, Expression.Constant(defualtValue, method.ReturnType));//有返回值是必须设置默认值
  41. block = Expression.Block(new ParameterExpression[] { resultTemp }, pre, assigment, post, returnEx, lblEx);
  42. #endregion
  43. }
  44. else
  45. {
  46. #region 无返回值处理
  47. block = Expression.Block(pre, execute, post);
  48. #endregion
  49. }
  50. var lumbda = Expression.Lambda<T>(block, listParameters.ToArray());
  51. return lumbda.Compile();
  52. }
  53. public event Action PreMethodExecute;
  54. private void Pre()
  55. {
  56. if (PreMethodExecute != null)
  57. {
  58. PreMethodExecute();
  59. }
  60. }
  61. public event Action PostMethodExecute;
  62. private void Post()
  63. {
  64. if (PostMethodExecute != null)
  65. {
  66. PostMethodExecute();
  67. }
  68. }
  69. }
  70. }