使用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.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 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.SampleClasscall 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.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动态代理相关推荐
- AspectCore动态代理中的拦截器详解(一)
前言 在上一篇文章使用AspectCore动态代理中,简单说明了AspectCore.DynamicProxy的使用方式,由于介绍的比较浅显,也有不少同学留言询问拦截器的配置,那么在这篇文章中,我们来 ...
- 聊聊AspectCore动态代理中的拦截器(一)
前言 在上一篇文章使用AspectCore动态代理中,简单说明了AspectCore.DynamicProxy的使用方式,由于介绍的比较浅显,也有不少同学留言询问拦截器的配置,那么在这篇文章中,我们来 ...
- 实现一个基于动态代理的 AOP
实现一个基于动态代理的 AOP Intro 上次看基于动态代理的 AOP 框架实现,立了一个 Flag, 自己写一个简单的 AOP 实现示例,今天过来填坑了 目前的实现是基于 Emit 来做的,后面有 ...
- .NET 下基于动态代理的 AOP 框架实现揭秘
.NET 下基于动态代理的 AOP 框架实现揭秘 Intro 之前基于 Roslyn 实现了一个简单的条件解析引擎,想了解的可以看这篇文章 基于 Roslyn 实现一个简单的条件解析引擎 执行过程中会 ...
- 【spring】动态代理
代理 动态代理 特点:字节码随用随创建,随用随加载 作用:不修改源码的基础上对方法增强 分类:基于接口的动态代理.基于子类的动态代理 基于接口的动态代理: 涉及的类:Proxy 提供者:JDK ...
- (转)面试必备技能:JDK动态代理给Spring事务埋下的坑!
一.场景分析 最近做项目遇到了一个很奇怪的问题,大致的业务场景是这样的:我们首先设定两个事务,事务parent和事务child,在Controller里边同时调用这两个方法,示例代码如下: 1.场景A ...
- Java动态代理和静态代理区别
静态代理 package staticproxy;/*** 接口* @author newtouch**/ public interface IHello {public void sayHello( ...
- java动态代理【一】
java动态代理的定义:为其他目标类的方法增加切面的逻辑,即在执行目标类方法的时候,先去执行一段如校验检测的逻辑代码.java通俗一点就是生成一个继承目标类的子类,并在每个调用方法都添加一段逻辑. 应 ...
- 支撑Java框架的基础技术:泛型,反射,动态代理,cglib
以Spring为例要想看明白他的源码需要彻底理解Java的一些基础技术泛型,反射同时对于一些高级技术例如动态代理,cglib和字节码技术也需要掌握,下面就按章节来一一说清楚这些技术的核心部分,最后手写 ...
最新文章
- 树链剖分——线段树区间合并bzoj染色
- 图模型+Bert香不香?完全基于注意力机制的图表征学习模型Graph-Bert
- MDT2008部署之三LTI部署之二
- Vue学习之路1 小白起步
- sklearn自学指南(part10)--Lasso及多任务Lasso
- AjaxControlToolkit控件效果演示
- 国足0:2不敌韩国 郑智:结果遗憾 对年轻球员是财富
- 2016 Multi-University Training Contest 10
- git stash (保存当前的工作现场)
- 绿色建筑评价标准(GB/T 50378-2006)
- win7 64bit部署SharePoint Server2010
- ps入门第10天_ps色彩平衡ps色相饱和度
- Matlab中写M文件及调用
- word文件退出只读模式
- 40种让孩子爱上阅读的好方法!转给家长
- MySQL(三) 完整性约束
- HTML期末学生大作业-在线电影网站html+css+javascript
- oracle vbo4582,4582是什么意思
- Freemarker导出复杂Excel图文教程
- 亚马逊AWS进入中国
热门文章
- Badboy自动化测试工具11 导出脚本用于Jmeter并发测试
- JDK5.0新特性--可变参数
- 文件用户如何将一个有界面的正常app和一个或多个越狱插件.deb同时安装到手机上...
- Oracle结构设计技巧(访问数据库象访问内存一样 快)
- MongoDB服务无法启动,原因居然是...
- 2021.NET大会日程首发!行程亮点全曝光!
- C# VS生成后事件命令行
- 生产力提升! 自己动手自定义Visual Studio 2019的 类创建模板,制作简易版Vsix安装包...
- .NET Core HttpClient请求异常分析
- 应对「高并发」的思路