使用.net core中的类DispatchProxy实现AOP
在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是软件开发中的一个热点,利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性。
比如说三层的调用:UI => BLL => DAL,正常来说我们会在UI层调用BLL层某个类的某个方法,然后BLL层某个类的某个方法又会调用DAL层某个类的某个方法,可以说通常情况下我们都是这么干的;如果说UI调BLL、BLL调DAL是纵向的话,那么AOP就是横向的,AOP可以做到在调用BLL层或DAL层任意方法之前之后做一些统一的逻辑处理。
AOP的典型应用场景:日志记录、权限验证、异常处理、缓存等
目前,可以实现AOP的类库也有很多,如下:
AspectCore
Unity
Castle DynamicProxy
Dora.Interception
但是在.net core中有DispatchProxy类(命名空间:System.Reflection),提供实例化代理对象和处理其方法调度的机制,借助它我们可以自己实现AOP,直接看示例
定义一个消息接口IMessage,其中有一个发送消息Send和接收消息Receive的方法定义:
public interface IMessage { void Send(string content); void Receive(string content); }
定义电子邮件类EmailMessage实现消息接口IMessage,实现使用电子邮件发送和接收消息:
public class EmailMessage : IMessage { public void Send(string content) { Console.WriteLine("Send Email:" + content); } public void Receive(string content) { Console.WriteLine("Receive Email:" + content); } }
定义日志拦截器LogDispatchProxy 继承自DispatchProxy类,重写基类Invoke方法并在目标方法调用前后加上所需业务逻辑;然后定义TargetClass属性,该属性是目标方法所属类的实例
public class LogDispatchProxy : DispatchProxy { public object TargetClass { get; set; } protected override object Invoke(MethodInfo targetMethod, object[] args) { Write("方法执行前"); var result = targetMethod.Invoke(TargetClass, args); Write("方法执行后"); return result; } private void Write(string content) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine(content); Console.ResetColor(); } }
使用:
class Program { static void Main(string[] args) { //使用DispatchProxy类的静态方法Create生成代理类,其中Create是个泛型方法,泛型有两个值,第一个值必须是接口,第二个值必须是DispatchProxy的子类 IMessage messageDispatchProxy = DispatchProxy.Create<IMessage, LogDispatchProxy>(); //创建一个实现了IMessage接口的类的实例,并赋值给代理类的TargetClass属性 ((LogDispatchProxy)messageDispatchProxy).TargetClass = new EmailMessage(); messageDispatchProxy.Send("早上好"); Console.WriteLine("======================================="); messageDispatchProxy.Receive("中午好"); Console.ReadKey(); } }
执行结果
我的理解:通过DispatchProxy.Create创建的代理类messageDispatchProxy 就是一个LogDispatchProxy类,并且利用我们提供的的实例实现了IMessage接口,所以messageDispatchProxy可以强转为LogDispatchProxy或IMessage
至此,我们没有通过任何第三方类库,自己实现了一个AOP