一、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、动态代理