使用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的代理:
?static void Main(string[] args) ? ?{ProxyGeneratorBuilder proxyGeneratorBuilder = new ProxyGeneratorBuilder();IProxyGenerator proxyGenerator = proxyGeneratorBuilder.Build();SampleInterface sampleInterface = proxyGenerator.CreateInterfaceProxy<SampleInterface>();Console.WriteLine(sampleInterface);sampleInterface.Foo();Console.ReadKey();} }
public class SampleInterceptor : AbstractInterceptorAttribute{ ?
?public override Task Invoke(AspectContext context, AspectDelegate next) ? ?{Console.WriteLine("call interceptor"); ? ? ?
? ?return context.Invoke(next);} }
? ?public class SampleClass : SampleInterface{ ?
? ??public virtual void Foo() { } }[SampleInterceptor]
? ??public interface SampleInterface{ ? ?void Foo(); }
將會輸出:
AspectCore.DynamicGenerated.SampleInterface1call interceptor同時,IProxyGenerator提供了若干重載的擴展方法來創建已有類或接口實例的代理,可在ProxyGeneratorExtensions中找到并使用它們。
在IoC中使用AspectCore.DynamicProxy
AspectCore在設計之初就考慮AOP和IoC的集成使用,并提供AOP抽象接口以兼容不同IoC,目前已實現和AspectCore.DynamicProxy集成的IoC框架有:
-
AspectCore.Injector(AspectCore Framework的內置IoC)
-
Microsoft.Extensions.DependencyInjection(Asp.Net Core的內置DI框架)
-
Autofac
下面我們分別看一下在三個IoC中如何使用AspectCore.DynamicProxy。
AspectCore.Injector
AspectCore.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.SampleClasscall interceptorMicrosoft.Extensions.DependencyInjection
AspectCore提供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.SampleClasscall interceptorAutofac
AspectCore提供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.SampleClasscall interceptor有問題反饋
如果您有任何問題,請提交?Issue?給我們。
Github :?https://github.com/dotnetcore/AspectCore-Framework
AspectCore QQ群: 306531723
原文:http://www.cnblogs.com/liuhaoyang/p/aspectcore-getting-started.html
.NET社區新聞,深度好文,歡迎訪問公眾號文章匯總 http://www.csharpkit.com
總結
以上是生活随笔為你收集整理的使用AspectCore动态代理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如果不懂Service mesh,就不要
- 下一篇: 通过 Visual Studio 的“代