C# AOP实现原理

AOP

AOP(Aspect Orient Programming),面向方面(切面)编程,是OOP面向对象的一种补充。OOP将对象进行模块划分,独立处理,而AOP则是将模块间各种横切关注点集合起来处理,比如事务管理、日志、缓存等等。AOP实现主要分为静态代理和动态代理。

何为切面

​ 一个与业务代码没有任何耦合的代码段。如日志记录,发送邮件等等。一切能为代码所有且能和代码充分解耦的代码都可以作为一个业务代码的切面。

AOP使用场景:

我们提交一个订单的时候,在提交前需要对参数进行校验,在提交后对订单进行日志记录。

static void Submit(Order order)
        {
            IOrderHandle orderHandle = new OrderHandle();

            //参数校验
            Console.WriteLine("参数校验");

            orderHandle.Submit(order);

            //日志记录
            Console.WriteLine("日记记录");
        }

上面就是典型的面向过程的写法,在每一个执行方法的前和后都需要写重复的代码,重复的操作,当系统越来越庞大,这种重复的代码就越多,修改起来就困难重重,牵一发而动全身。这时候就需要引入AOP来解决这些重复性的操作。

AOP-静态代理:

静态代理的意思是通过编写代理类,重写相应的业务类,在执行的前后执行相关操作。在编译的时候直接调用代理类来执行。

继续上面的提交订单例子:

1、定义订单类
 public class Order
    {
        /// <summary>
        /// 金额
        /// </summary>
        public double Amount { get; set; }

        /// <summary>
        /// 数量
        /// </summary>
        public int Number { get; set; }

        /// <summary>
        /// 商品名称
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 单价
        /// </summary>
        public int Price { get; set; }
    }
2、定义订单处理接口:
 public interface IOrderHandle
    {
        void Submit(Order order);
    }
3、实现订单处理接口
 public class OrderHandle : IOrderHandle
    {
        public void Submit(Order order)
        {
            Console.WriteLine("提交订单");
        }
    }
4、编写订单处理代理类

构造函数引入OrderHandle,重新实现Submit方法,在调用之后增加对应的代码处理。

public class OrderHandleProxy : IOrderHandle
    {

        private IOrderHandle _orderHandle;

        public OrderHandleProxy(IOrderHandle orderHandle)
        {
            _orderHandle = orderHandle;
        }

        public void Submit(Order order)
        {
            PreSubmit(order);
            _orderHandle.Submit(order);
            AfterSubmit(order);
        }

        private void PreSubmit(Order order)
        {
            Console.WriteLine("提交订单前进行数据校验");
        }

        private void AfterSubmit(Order order)
        {
            Console.WriteLine("提交订单后进行日志记录");
        }
    }
5、调用代理类
 static void Main(string[] args)
        {

            #region 静态代理
            Order order = new Order { Amount = 2000, Number = 200 };

            OrderHandleProxy orderHandleInterceptor = new OrderHandleProxy(new OrderHandle());

            orderHandleInterceptor.Submit(order);
            #endregion

            Console.ReadKey();
        }
6、输出

image-20200404183007669

小结:

AOP本质上通过装饰者模式,增加原有业务类的功能,实现了横向切面的功能。

缺点:每一个业务类都需要手写一个代理类。因此就需要动态代理,通过给方法打属性等等方法在编译的时候动态生成代理类。

动态代理实现比较复杂,常见的可以通过Emit来实现。
原文地址:https://www.cnblogs.com/roluodev/p/12633197.html