在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,经过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,是函数式编程的一种衍生范型。利用AOP能够对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度下降,提升程序的可重用性,同时提升了开发的效率。编程
在.NET Core中比较好的AOP框架有一个叫作Aspect的这样的一个框架, 它是一个国产的!如何引入AspectCore? 能够直接nuget。浏览器
这AspectCore中须要建立一个拦截器通常继承自 AbstractInterceptorAttribute。而且实现它的 Invoke 方法 。框架
其中第一个参数是上下文,next是执行的委托方法,经过这个委托能够执行被拦截的方法。异步
//每一个被拦截的方法中执行 public async override Task Invoke(AspectContext context, AspectDelegate next) { try { Console.WriteLine("Before service call"); await next(context); } catch (Exception) { Console.WriteLine("Service threw an exception!"); throw; } finally { Console.WriteLine("After service call"); } }
首先咱们能够建立一个须要被代理拦截的类(必须是public方法是虚方法且被标记,也必须使用MVC中的Filter命名规范)。这个方法也能够是异步的!async
public class Person { [CustomInterceptor] public virtual void Say(string msg) { Console.WriteLine("service calling..."+msg); } }
如何进行代理? 须要经过ProxyGeneratorBuilder 来代理对象,注意 p 指向的对象是 AspectCore 生成的 Person 的动态子类的对象,直接 new Person是没法被拦截的。ide
static void Main(string[] args) { ProxyGeneratorBuilder proxyGeneratorBuilder = new ProxyGeneratorBuilder(); using (IProxyGenerator proxyGenerator = proxyGeneratorBuilder.Build()) { Person p = proxyGenerator.CreateClassProxy<Person>(); p.Say("zaranet"); } }
上面说到咱们不能够直接new这个person,那如今咱们调试一下,一探究竟!!!咱们看看这个p是个什么类型。函数式编程
噫?为何这个p不是AspectPollyIdn.Person?而是AspectCore.DynamicGenerated.Person?不妨把这个p的父类给打印出来,来瞅瞅。函数
static void Main(string[] args) { ProxyGeneratorBuilder proxyGeneratorBuilder = new ProxyGeneratorBuilder(); using (IProxyGenerator proxyGenerator = proxyGeneratorBuilder.Build()) { Person p = proxyGenerator.CreateClassProxy<Person>(); Console.WriteLine(p.GetType().BaseType); p.Say("zaranet"); } }
如今的对象是咱们了,也就是它的父类,那这个时候你就绝对要明白了,为何咱们的被代理类是虚方法,也就是说它用子类类重写了咱们被代理类的虚方法,也就实现了AOP,那么呢这也就是Aspect.Core的原理。大概简单的就是这样。post
如今你已经了解了AspectCore的原理了,但回头发现每次来建立这些对象都很是繁琐,咱们只想去使用AspectCore经过CreateClassProxy()来建立咱们想要的代理对象,那么如今咱们能够使用AspNetCore的依赖注入解决这个问题。测试
首先呢,咱们引用AspectCore.Extensions.DependencyInjection,这是AspectCore给咱们的一个DI框架。再把Startup中的ConfigureServices进行改造。
public IServiceProvider ConfigureServices(IServiceCollection services) { services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); services.AddSingleton<Person>(); return services.BuildAspectInjectorProvider(); }
随便建立一个类 继承与AbstractInterceptorAttribute ,重写方法,再添加一个Person。
public class Person { [CustomInterceptor] public virtual void Say(string msg) { // } }
在API中重载进行依赖注入。下面咱们进行postman进行测试,由于已经关闭了浏览器浏览。
private Person p; public ValuesController(Person p) { this.p = p; }
OK,成功。