如何使用AspectCore动态代理?
发布时间:2019-12-30    来源: 118云vps       阅读:
                    
	    最近越来越多的同学关注到AspectCore,并且提出不少中肯的建议,其中最多的提议是希望能够看到更多的关于AspectCore使用方式的文章和Demo。那么在这篇文章里,我们就来聊聊AspectCore核心之一的动态代理。
	    如何使用AspectCore动态代理?

	    动态VPN代理
	    在.NET平台中,静态织入和动态代理是实现AOP的两种方式。其中静态织入在编译时通过在MSBiuld执行自定义的Build Task来拦截编译过程,在生成的程序集里插入自己的IL。而动态代理则是在运行时通过Emit技术生成动态程序集和动态代理类型从而对目标方法进行拦截。不管那种方式,都需要对MSIL有足够的理解,如果读者想要学习MSIL相关的技术,我在这里推荐《NET探秘MSIL权威指南》一书。
	    AspectCore使用了动态代理作为AOP的实现,而不使用理论上性能更优的静态织入实现,是由于个人觉得动态代理方式可以做到更好的IoC进行集成并且能够在切面中获取更多的运行时元数据信息,并且在经过不断优化后,AspectCore动态代理的性能已经不落后静态织入的实现方式。
	    如何使用
	    在之前的文章里,只是简单的介绍了AspectCore,导致了很多同学不知道如何在项目里使用AspectCore(^~^,求轻拍~)。下面就来讲一下如何在IoC环境和非IoC环境里使用AspectCore的AOP。
	    首先通过nuget获取AspectCore:
	    Install-Package AspectCore.Core
	    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的代理:
	    class Program
	    {
	    static void Main(string[] args)
	    {
	    ProxyGeneratorBuilder proxyGeneratorBuilder = new ProxyGeneratorBuilder();
	    IProxyGenerator proxyGenerator = proxyGeneratorBuilder.Build();
	    SampleInterface sampleInterface = proxyGenerator.CreateInterfaceProxy<SampleInterface,SampleClass>();
	    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.SampleInterface1
	    call 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.SampleClass
	    call interceptor
	    Microsoft.Extensions.DependencyInjection
	    AspectCore提供AspectCore.Extensions.DependencyInjection包集成Microsoft.Extensions.DependencyInjection和AspectCore.DynamicProxy。
	    通过nuget获取:
	    Install-Package AspectCore.Extensions.DependencyInjection
	    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
	    Autofac
	    AspectCore提供AspectCore.Extensions.Autofac包集成Autofac和AspectCore.DynamicProxy。
	    通过nuget获取:
	    Install-Package AspectCore.Extensions.Autofac
	    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
                    

