.net使用DispatchProxy

  • .net使用DispatchProxy已关闭评论
  • 117 次浏览
  • A+
所属分类:.NET技术
摘要

实现动态aop并注入 用表达式树调用目标方法创建一个DynamicDispatchProxy类继承DispatchProxy,字典key最好是由路劲名称+方法参数组成 

实现动态aop并注入 用表达式树调用目标方法

创建一个DynamicDispatchProxy类继承DispatchProxy,字典key最好是由路劲名称+方法参数组成 

public class DynamicDispatchProxy<T> : DispatchProxy {     /// <summary>     /// 目标类     /// </summary>     private T _this { get; set; }     /// <summary>     /// 进入前方法     /// </summary>     private Action<string> _last { get; set; }     /// <summary>     /// 退出后方法     /// </summary>     private Action<string, object?> _next { get; set; }     private void last(string _v)     {         try         {             _last.Invoke(_v);         }         catch (System.Exception)         {          }     }     private void next(string _v, object _v1)     {         try         {             _next.Invoke(_v, _v1);         }         catch (System.Exception)         {          }     }     private static ConcurrentDictionary<string, Delegate?> dic = new ConcurrentDictionary<string, Delegate?>();     protected override object? Invoke(MethodInfo? targetMethod, object?[]? args)     {         last(targetMethod.Name);         object obj = null;         try         {             var paramstype = targetMethod.GetParameters().Select(d => d.ParameterType).ToList();             var key =typeof(T).FullName+ targetMethod.Name + string.Join(' ', paramstype.Select(d => d.Name));             if (!dic.ContainsKey(key))             {                 List<ParameterExpression> listparame = new List<ParameterExpression>();                 for (int i = 0; i < paramstype.Count; i++)                 {                     listparame.Add(Expression.Parameter(paramstype[i]));                 }                 MethodCallExpression method = Expression.Call(Expression.Constant(_this), targetMethod, listparame);                 Delegate? lambda = Expression.Lambda(method, listparame).Compile();                 dic.TryAdd(key, lambda);             }             obj= dic[key].DynamicInvoke(args);              next(targetMethod.Name,obj);             return obj;         }         catch (System.Exception ex)         {              throw ex;         }     }     public T Create(){         ///BuildServiceProvider 获取方法         var imp = IServiceCollectionHelp.GetService<T>();         ///拦截实现类的type         var attributtype = imp.GetType().GetCustomAttribute<DynamicTypeAttribut>();         ///在这之前要先注入 拦截实现类才能获取 Impintercept这是接口定义拦截前和拦截后         var Impintercept = IServiceCollectionHelp.GetService<IIntercept>(attributtype.type);         object o = Create<T, DynamicDispatchProxy<T>>();         DynamicDispatchProxy<T> pro=(DynamicDispatchProxy<T>)o;         ///赋值给上面委托         pro._this = imp;         pro._last = Impintercept.Last;         pro._next = Impintercept.Next;         return (T)o;     } }

创建一个特性类 来获取拦截实现类的type !DynamicTypeAttribut

 [AttributeUsage(AttributeTargets.Class)]     public class DynamicTypeAttribut:Attribute     {         public Type type;         public DynamicTypeAttribut(Type type){             this.type=type;         }     }

定义拦截接口 IIntercept

  public interface IIntercept     {         void Last(string name);         void Next(string name,object? obj);     }

拦截的目标

public interface ITest {     void Write();     int Add(int v1,int v2); }
///这里是Intercept是实现类 [DynamicTypeAttribut(
typeof(Intercept))] public class Test : ITest { public int Add(int v1, int v2) { Console.WriteLine(nameof(Add)); return v1+v2; } public void Write() { Console.WriteLine(this.GetHashCode()); } }

拦截方法的实现

public class Intercept : IIntercept {     public void Last(string name)     {         Console.WriteLine(this.GetHashCode());          Console.WriteLine("进入"+name);     }      public void Next(string name, object? obj)     {         Console.WriteLine("推出"+name);         if( obj !=null)             Console.WriteLine("返回值"+obj);     } }

注入

///注入拦截实现类 不然获取不到 builder.Services.AddScoped< Intercept>(); ///这里也要注入一次  不然也获取不到 builder.Services.AddScoped<ITest, Test>(); var _ = new DynamicDispatchProxy<ITest>(); IServiceCollectionHelp.serviceProvider = builder.Services.BuildServiceProvider(); builder.Services.AddScoped(typeof(ITest), d => {         return _.Create();///创建 })