internal class DynamicProxy<T> : DispatchProxy { public T? decorated { get; set; }//目标类 public Action<object?[]?>? _BeforeAction { get; set; } // 动作之前执行 public Action<object?[]?, object>? _AfterAction { get; set; } // 动作之后执行 public Action<Exception>? _CatchExceptionAction { get; set; } // 捕获异常之后执行 protected override object? Invoke(MethodInfo? targetMethod, object?[]? args) { Exception exception = null; Before(args); object result = null; try { //调用实际目标对象的方法 result = targetMethod?.Invoke(decorated, args); } catch (Exception ex) { exception = ex; } After(args, result); // 堆代码 duidaima.com //调用完执行方法后的委托,如果有异常,抛出异常 if (exception != null) { CatchException(exception); } return result; } /// <summary> /// 创建代理实例 /// </summary> /// <param name="decorated">代理的接口类型</param> /// <param name="beforeAction">方法执行前执行的事件</param> /// <param name="afterAction">方法执行后执行的事件</param> /// <param name="catchException">异常捕获后执行的事件</param> /// <returns></returns> public T Create(T decorated, Action<object?[]?> beforeAction, Action<object?[]?, object> afterAction, Action<Exception> catchException) { // 调用DispatchProxy 的Create 创建一个新的T object proxy = Create<T, DynamicProxy<T>>(); DynamicProxy<T> proxyDecorator = (DynamicProxy<T>)proxy; proxyDecorator.decorated = decorated; //把自定义的方法委托给代理类 proxyDecorator._AfterAction = afterAction; proxyDecorator._BeforeAction = beforeAction; proxyDecorator._CatchExceptionAction = catchException; return (T)proxy; } private void Before(object?[]? args) { try { _BeforeAction.Invoke(args); } catch (Exception ex) { Console.WriteLine($"执行之前异常:{ex.Message}"); } } private void After(object?[]? args, object? result) { try { _AfterAction.Invoke(args, result); } catch (Exception ex) { Console.WriteLine($"执行之后异常:{ex.Message}"); } } private void CatchException(Exception ex) { _CatchExceptionAction(ex); } }2. 创建拦截器属性
/// <summary> /// 自定义拦截器特性 /// </summary> [AttributeUsage(AttributeTargets.Class)] internal class InterceptAttribut : Attribute { public Type Type { get; set; } public InterceptAttribut(Type type) { this.Type = type; } }3. 创建动态代理工厂类
class DynamicProxyFactory { /// <summary> /// 创建代理实例 /// </summary> /// <param name="decorated">代理的接口类型</param> /// <returns></returns> public static T Create<T>() { var decorated = ServiceHelp.GetService<T>(typeof(T)); var type = decorated.GetType(); var interceptAttribut = type.GetCustomAttribute<InterceptAttribut>(); var interceptor = ServiceHelp.GetService<IInterceptor>(interceptAttribut.Type); //创建代理类 var proxy = new DynamicProxy<T>().Create(decorated, interceptor.BeforeExecuted, interceptor.AfterExecuted, interceptor.CatchException); return proxy; } }4. 创建ServiceHelp
internal class ServiceHelp { //实例化Autofac容器 private static ContainerBuilder builder = new ContainerBuilder(); public static IContainer? serviceProvider { get; set; } public static void BuildServiceProvider() { //注册InstanceModule组件 builder.RegisterModule<InstanceModule>(); //创建容器 serviceProvider = builder.Build(); } internal static T GetService<T>(Type serviceType) { if (serviceProvider.IsRegistered(serviceType)) { return (T)serviceProvider.Resolve(serviceType); } return default(T); } }5. 创建AOP切面
/// <summary> /// 自定义拦截器接口 /// </summary> interface IInterceptor { /// <summary> /// 执行前 /// </summary> /// <param name="args"></param> void BeforeExecuted(object?[]? args); /// <summary> /// 执行后 /// </summary> /// <param name="args">参数</param> /// <param name="result">返回值</param> void AfterExecuted(object?[]? args, object? result); void CatchException(Exception ex); } /// <summary> /// 方法执行的切面 /// </summary> class ExecutAOP : IInterceptor { public void AfterExecuted(object?[]? args, object? result) { Console.WriteLine($"拦截器中方法后执行~~~~"); } public void BeforeExecuted(object?[]? args) { if (args != null && args.Length > 0 && args[0] == null) throw new Exception("参数错误"); Console.WriteLine($"拦截器中方法前执行~~~~"); } public void CatchException(Exception ex) { Console.WriteLine($"拦截器中捕获到了异常~~~~\r\n{ex.InnerException.Message}"); } }6. 创建测试模型
interface ITransportation { public void Run(); public void Eat(string food); } [InterceptAttribut(typeof(ExecutAOP))] class Horse : ITransportation { public void Eat(string food) { Console.WriteLine($"小马儿吃了{food}~~~~~~~~~~~~"); } public void Run() { Console.WriteLine("马儿马儿快马加鞭~~~~~~~~~~~~"); throw new Exception("小马儿掉沟里了"); } }7.测试场景
static void Main(string[] args) { ServiceHelp.BuildServiceProvider(); var hours = DynamicProxyFactory.Create<ITransportation>(); hours.Eat("新鲜牧草"); Console.ReadLine(); }输出:
static void Main(string[] args) { ServiceHelp.BuildServiceProvider(); var hours = DynamicProxyFactory.Create<ITransportation>(); hours.Run(); Console.ReadLine(); }
输出:
image.png再Horse的Run方法中我们主动抛出了异常,然后从控制台输出可以看到,异常也被拦截器拦截,并做了处理输出拦截器中捕获到了异常及异常信息。