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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/322842.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

P1131-[ZJOI2007]时态同步【树形dp】

正题 题目大意 一棵树&#xff0c;可以增长边权长度&#xff0c;要求根节点要每个叶子节点路径长度相等&#xff0c;求最少增加次数。 解题思路 肯定优先修改上面的边&#xff0c;因为这样可以影响最多的点&#xff0c;那么对于每个节点我们都要使它到每个它子树中叶子节点的…

已经安装完成mysql后wamp怎么配置

如果之前安装过mysql&#xff0c;然后想要安装wamp&#xff0c;那么怎么配置呢 先安装好wamp&#xff0c;然后在以下目录中修改my.ini 将密码改为自己的mysql密码即可 这时你发现启动wamp还是黄的 不要慌&#xff0c;因为你已经安装过了wamp&#xff0c;所以wamp自己的mys…

SpringBoot2.1.9 分布式锁ShedLock不执行坑

一、起由 Configuration EnableScheduling EnableSchedulerLock(defaultLockAtMostFor "PT30S") public class TimerTaskConfig implements SchedulingConfigurer {Beanpublic LockProvider scheduledLockConfiguration(RedisConnectionFactory redisConn) {return…

P3891-[GDOI2014]采集资源【背包,dp】

正题 题目大意 nnn个苦力&#xff0c;aia_iai​资源招募&#xff0c;每sss生产bib_ibi​资源。开始有mmm点资源&#xff0c;求最短时间内生产ttt点资源。 解题思路 先计算fif_ifi​表示花费iii点资源最多可以获得多少生产力。 然后gi,jg_{i,j}gi,j​表示前iii个单位时间资源为…

通过 Visual Studio 的“代码度量值”来改进代码质量

1 软件度量值指标 1.1 可维护性指数 表示源代码的可维护性&#xff0c;数值越高可维护性越好。该值介于0到100之间。绿色评级在20到100之间&#xff0c;表明该代码具有高度的可维护性&#xff1b;黄色评级在10到19之间&#xff0c;表示该代码适度可维护&#xff1b;红色评级在0…

php如何接收前端返回的各种类型的数据

之前学习node后端的时候&#xff0c;因为始终无法在网上找到接收json数据的函数&#xff0c;所以后来就放弃了。最近又心血来潮&#xff0c;想学习php. 这次已经有了之前学习php的基础&#xff0c;所以直接入手thinkphp5.0 这次php的学习&#xff0c;主要是为了解决之前遗留的问…

面试官让我讲讲Java中的锁,我笑了

转载自 面试官让我讲讲Java中的锁&#xff0c;我笑了 在读很多并发文章中&#xff0c;会提及各种各样锁如公平锁&#xff0c;乐观锁等等&#xff0c;这篇文章介绍各种锁的分类。介绍的内容如下&#xff1a; 公平锁/非公平锁 可重入锁 独享锁/共享锁 互斥锁/读写锁 乐观锁…

ASP.NET Core 认证与授权[5]:初识授权

经过前面几章的姗姗学步&#xff0c;我们了解了在 ASP.NET Core 中是如何认证的&#xff0c;终于来到了授权阶段。在认证阶段我们通过用户令牌获取到用户的Claims&#xff0c;而授权便是对这些的Claims的验证&#xff0c;如&#xff1a;是否拥有Admin的角色&#xff0c;姓名是否…

P1850-换教室【数学期望,dp,Floyd】

正题 题目大意 一张图&#xff0c;nnn次&#xff0c;每次在cic_ici​上课&#xff0c;可以申请换课室到did_idi​&#xff0c;成功概率kik_iki​。求最短需要走的路径的期望长度 解题思路 先FlodyFlodyFlody预处理多源最短路&#xff0c;然后考虑dpdpdp 设fi,j,0/1f_{i,j,0/…

uni-app打包h5

如果我们想打包成直接浏览的h5&#xff0c;我们需要配置manifest.json这个文件&#xff0c;在其中的h5配置中加入publicPath配置&#xff0c;配置如下&#xff1a; 代码为&#xff1a; "h5" : {"publicPath": "./"},配置好这个后&#xff0c;以后…

SpringBoot2.1.9 多MongoDB配置template

一、配置文件 pom.xml <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency> application.yml spring:application:name: double-mongoprofiles:active…

[52ABP实战系列] .NET CORE实战入门视频课程出来啦

“ .NET CORE实战入门视频&#xff0c;要是有讲的不好的地方&#xff0c;还请留言。” 早安&#xff01; 各位道友好&#xff0c;.NET CORE入门视频的第一章已经录制完毕了。视频会放在传课网、网易云课堂及segment fault。 本来想的是第一章合计6个小节就可以播放完毕的&#…

P2473-[SCOI2008]奖励关【数学期望,状压dp】

正题 题目大意 kkk轮&#xff0c;每轮抛出随机一个宝物&#xff0c;若一个宝物的前提集合SiS_iSi​之前都拿到过&#xff0c;那么就可以拿这个并获得pip_ipi​分。 求最大期望分数 解题思路 考虑状态压缩dpdpdp&#xff0c;状态表示宝物是否拿过。 fi,jf_{i,j}fi,j​表示第iii…

vue项目总结

axios axios.defaults.baseURL "http://localhost/public/index/video/" axios.defaults.headers.post[Content-Type] application/json Vue.prototype.$http axios this.$http.post(dunmylist,this.form).then(res>{console.log(res.data);})表单验证 1、r…

SpringBoot2.1.9 多Redis Lettuce配置

一、配置文件 pom.xml <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId> </dependency> application.yml spring:application:name: double-redis-lettuceprofiles:…

ASP.NET Core缓存静态资源

背景 缓存样式表&#xff0c;JavaScript或图像文件等静态资源可以提高您网站的性能。在客户端&#xff0c;总是从缓存中加载一个静态文件&#xff0c;这样可以减少对服务器的请求数量&#xff0c;从而减少获取页面及其资源的时间。在服务器端&#xff0c;由于它们的请求较少&am…

P3830-[SHOI2012]随机树【数学期望,dp】

正题 题目大意 开始的时候一个点&#xff0c;然后等概率随机选一个叶子节点展开成两个&#xff0c;求nnn个叶子节点的树的叶子节点平均深度和最大深度期望。 解题思路 平均深度很好求&#xff0c;因为每展开一个&#xff0c;叶子节点总深度就加上个2。 所以gigi−12ig_{i}g_…

【程序员】保持一颗虚心好学的心态去敲代码

最近&#xff0c;我感觉是自己突破最大的一段时间&#xff0c;为什么呢&#xff1f;主要是打通了接口这一块&#xff0c;就是用postman发送各种数据&#xff0c;我都能用后端接受到相关数据&#xff0c;并且解析出来。 在这之前我尝试过spring boot 和node&#xff0c;前者是太…

SpringBoot @Resource注入的坑

一、场景复现 双kafka消费者配置 &#xff08;1&#xff09;第一个kafka public class OneKafkaConfig {Beanpublic KafkaListenerContainerFactory oneKafkaFactory(Resource ConsumerFactory oneConsumerFactory) {ConcurrentKafkaListenerContainerFactory factory new …

跟着老桂学ASP.NET Core 2.0

.net core作为微软开发技术中跨平台的利器&#xff0c;2.0的发布已经有一段时间了&#xff0c;asp.net core是新一代微软的BS开发框架&#xff0c;同时兼容.net core和.net framework&#xff0c;它的出现&#xff0c;使基于微软体系的BS开发迎来新的契机&#xff0c;开源&…