|
实现动态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);
- }<br>///这里是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();///创建
- })
复制代码
来源:https://www.cnblogs.com/bay-max-/archive/2023/03/03/17175481.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作! |
|