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、动态代理
点到为止