使用AspectCore动态代理
前言
最近越来越多的同学关注到AspectCore,并且提出不少中肯的建议,其中最多的提议是希望能够看到更多的关于AspectCore使用方式的文章和Demo。那么在这篇文章里,我们就来聊聊AspectCore核心之一的动态代理。
动态代理在.NET平台中,静态织入和动态代理是实现AOP的两种方式。其中静态织入在编译时通过在MSBiuld执行自定义的Build Task来拦截编译过程,在生成的程序集里插入自己的IL。而动态代理则是在运行时通过Emit技术生成动态程序集和动态代理类型从而对目标方法进行拦截。不管那种方式,都需要对MSIL有足够的理解,如果读者想要学习MSIL相关的技术,我在这里推荐《NET探秘MSIL权威指南》一书。
AspectCore使用了动态代理作为AOP的实现,而不使用理论上性能更优的静态织入实现,是由于个人觉得动态代理方式可以做到更好的IoC进行集成并且能够在切面中获取更多的运行时元数据信息,并且在经过不断优化后,AspectCore动态代理的性能已经不落后静态织入的实现方式。
在之前的文章里,只是简单的介绍了AspectCore,导致了很多同学不知道如何在项目里使用AspectCore(^~^,求轻拍~)。下面就来讲一下如何在IoC环境和非IoC环境里使用AspectCore的AOP。
首先通过nuget获取AspectCore:
AspectCore中动态代理api在AspectCore.DynamicProxy命名空间中,所以我们需要先引入命名空间
using AspectCore.DynamicProxy;在非IoC环境中,只使用AOP的话,AspectCore提供了ProxyGeneratorBuilder作为代理生成器创建的入口
ProxyGeneratorBuilder proxyGeneratorBuilder = new ProxyGeneratorBuilder(); IProxyGenerator proxyGenerator = proxyGeneratorBuilder.Build();IProxyGenerator提供了CreateClassProxy方法创建class代理和CreateInterfaceProxy方法创建interface代理,创建的代理类被定义在命名为AspectCore.DynamicProxy.Generator的动态程序集中,并且代理类使用AspectCore.DynamicGenerated命名空间。
我们先来定义一个简单的拦截器,接着定义一个interface和它的简单实现,并创建interface的代理:
将会输出:
AspectCore.DynamicGenerated.SampleInterface1 call interceptor同时,IProxyGenerator提供了若干重载的扩展方法来创建已有类或接口实例的代理,可在ProxyGeneratorExtensions中找到并使用它们。
在IoC中使用AspectCore.DynamicProxyAspectCore在设计之初就考虑AOP和IoC的集成使用,并提供AOP抽象接口以兼容不同IoC,目前已实现和AspectCore.DynamicProxy集成的IoC框架有:
下面我们分别看一下在三个IoC中如何使用AspectCore.DynamicProxy。
AspectCore.InjectorAspectCore.Injector中内置了对AspectCore.DynamicProxy的支持,所以我们可以直接使用它:
IServiceContainer serviceContainer = new ServiceContainer(); serviceContainer.AddType<SampleInterface, SampleClass>(); IServiceResolver serviceResolver = serviceContainer.Build(); SampleInterface sampleInterface = serviceResolver.Resolve<SampleInterface>(); Console.WriteLine(sampleInterface); sampleInterface.Foo();输出:
AspectCore.DynamicGenerated.SampleClass call interceptor Microsoft.Extensions.DependencyInjectionAspectCore提供AspectCore.Extensions.DependencyInjection包集成Microsoft.Extensions.DependencyInjection和AspectCore.DynamicProxy。
通过nuget获取:
AspectCore提供了针对IServiceCollection的扩展方法AddDynamicProxy注册动态代理的接口和相关拦截器配置,并需要使用BuildAspectCoreServiceProvider创建被DynamicProxy接管的ServiceProvider:
IServiceCollection services = new ServiceCollection(); services.AddTransient<SampleInterface, SampleClass>(); services.AddDynamicProxy(); IServiceProvider serviceProvider = services.BuildAspectCoreServiceProvider(); SampleInterface sampleInterface = serviceProvider.GetService<SampleInterface>(); Console.WriteLine(sampleInterface); sampleInterface.Foo();输出:
AspectCore.DynamicGenerated.SampleClass call interceptor AutofacAspectCore提供AspectCore.Extensions.Autofac包集成Autofac和AspectCore.DynamicProxy。
通过nuget获取:
AspectCore提供了针对ContainerBuilder的扩展方法RegisterDynamicProxy注册动态代理的接口和相关拦截器配置
ContainerBuilder builder = new ContainerBuilder(); builder.RegisterType<SampleClass>().As<SampleInterface>(); builder.RegisterDynamicProxy(); var container = builder.Build(); SampleInterface sampleInterface = container.Resolve<SampleInterface>(); Console.WriteLine(sampleInterface); sampleInterface.Foo();输出:
AspectCore.DynamicGenerated.SampleClass call interceptor 有问题反馈如果您有任何问题,请提交 Issue 给我们。
Github : https://github.com/dotnetcore/AspectCore-Framework
AspectCore QQ群: 306531723
posted @