- A+
所属分类:.NET技术
实现动态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();///创建 })