AOP

一、Aop是什么?

一段很常见的Aop经典代码示例:(AOP的实现原理应该也是如此,只不过它帮助我们做了方法拦截,

帮我们省去了大量重复代码,我们要做的仅仅是写好拦截前和拦截后需要处理的逻辑)

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
        }
        public string DosomeThing()
        {
            return "hello";
        }
        public string GetSomeOne()
        {
            try
            {
                var result = DosomeThing();
                //_logger.Information(result);
                return result;
            }
            catch (Exception e)
            {
                //_logger.Error(e.Message);
                return null;
            }
        }
        public string GetOtherOne()
        {
            try
            {
                var result = DosomeThing();
                //_logger.Information(result);
                return result;
            }
            catch (Exception e)
            {
                //_logger.Error(e.Message);
                return null;
            }
        }
    }

这是一段很典型的面向过程的代码,我们可以看到有相同的异常处理逻辑,

如果我们想要避免重复的代码,我们至少可以把异常处理封装一下:

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
        }
        public string DosomeThing()
        {
            return "hello";
        }
        public string GetOtherOne()
        {
            return TryRun<String>(() => DosomeThing());
        }
        public T TryRun<T>(Func<T> action)
        {
            try
            {
                return action.Invoke();
            }
            catch (Exception e)
            {
                //_logger.Error(e.Message);
                return default(T);
            }
        }
    }

上面仅仅把重复的异常处理封装一下,

但是真实的方法代码与日志代码纠缠在一起,违反了 单一责任原则,

return TryRun<String>(() => DosomeThing());

此语句是整篇代码的精髓,相当于函数委托调用任意函数,你可以封装一个记录日志、记录执行时间、缓存的比如:

_logger.Error(e.Message);传入 return TryRun<String>(() => DosomeThing());执行 //此句话不仅仅封装try catch 里面还可以写执行时间。

二、Aop实现几种方式

1、静态拦截

namespace ConsoleApp
{

    public class Order
    {
        public int Id { set; get; }
        public string Name { set; get; }
        public int Count { set; get; }
        public double Price { set; get; }
        public string Desc { set; get; }
    }

    public interface IOrderProcessor
    {
        void Submit(Order order);
    }
    public class OrderProcessor : IOrderProcessor
    {
        public void Submit(Order order)
        {
            Console.WriteLine("提交订单");
        }
    }

    public class OrderProcessorDecorator : IOrderProcessor
    {
        public IOrderProcessor OrderProcessor { get; set; }
        public OrderProcessorDecorator(IOrderProcessor orderprocessor)
        {
            OrderProcessor = orderprocessor;
        }
        public void Submit(Order order)
        {
            PreProceed(order);
            OrderProcessor.Submit(order);
            PostProceed(order);
        }
        public void PreProceed(Order order)
        {
            Console.WriteLine("提交订单前,进行订单数据校验....");
            if (order.Price < 0)
            {
                Console.WriteLine("订单总价有误,请重新核对订单。");
            }
        }
        public void PostProceed(Order order)
        {
            Console.WriteLine("提交带单后,进行订单日志记录......");
            Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "提交订单,订单名称:" + order.Name + ",订单价格:" + order.Price);
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Order order = new Order() { Id = 1, Name = "lee", Count = 10, Price = 100.00, Desc = "订单测试" };
            IOrderProcessor orderprocessor = new OrderProcessorDecorator(new OrderProcessor());
            orderprocessor.Submit(order);
            Console.ReadLine();
        }
    }
}

得到结果:

 它帮助我们做了方法拦截,帮我们省去了大量重复代码,我们要做的仅仅是写好拦截前和拦截后需要处理的逻辑。

2、动态代理

原文地址:https://www.cnblogs.com/fger/p/11362215.html