HTML5技术

使用AspectCore动态代理 - Lemon丶

字号+ 作者:H5之家 来源:H5之家 2017-11-21 11:01 我要评论( )

使用AspectCore动态代理 前言 最近越来越多的同学关注到AspectCore,并且提出不少中肯的建议,其中最多的提议是希望能够看到更多的关于AspectCore使用方式的文章和Demo。那么在这篇文章里,我们就来聊聊AspectCore核心之一的动态代理。 动态代理 在.NET平台

使用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:

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>(); 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框架有:

下面我们分别看一下在三个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 有问题反馈

如果您有任何问题,请提交 Issue 给我们。
Github : https://github.com/dotnetcore/AspectCore-Framework
AspectCore QQ群: 306531723

posted @

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • BootStrap的入门和响应式的使用 - Or_so

    BootStrap的入门和响应式的使用 - Or_so

    2017-11-21 10:07

  • 使用原生JavaScript的Canvas实现拖拽式图形绘制,支持画笔、线条、箭头、三角形、矩形、平行四边形、梯形以及多

    使用原生JavaScript的Canvas实现拖拽式图形绘制,支持画笔、线条、箭

    2017-11-09 16:05

  • Spring Boot使用thymeleaf模板时报错:Template might not exist or migh

    Spring Boot使用thymeleaf模板时报错:Template might not exist or

    2017-10-31 11:40

  • 实现输入框【输入填写+动态提示信息+下拉选择】 - 酒不醉心

    实现输入框【输入填写+动态提示信息+下拉选择】 - 酒不醉心

    2017-10-30 18:01

网友点评