Dora.Interception,为.NET Core度身打造的AOP框架:全新的版本

Dora.Interception 1.0(可以访问GitHub地址:https://github.com/jiangjinnan/Dora)推出有一段时间了,最近花了点时间将它升级到2.0,主要有如下的改进:

  • 提供了原生的动态代理生成底层框架Dora.DynamicProxy:之前依赖第三方框架Castle实现最底层的代理生成,但是它不支持基于Task的并行编程(也就是说通过它编写的Interceptor无法实现异步执行),所以我采用IL Emit的方式自行实现了这部分的功能,这些底层的功能实现在Dora.DynamicProxy中。

  • 提供了如下两种形式的拦截方案:

    • 基于实例封装:如果消费的类型是一个接口,那么提供的类型为动态生成的代理类,该代理类封装了目标对象。对于每一个动态生成的接口实现成员来说,它会负责执行应用的Interceptor。如果需要调用目标方法,被封装的目标对象的对应方法会被调用。这种拦截方案要求目标类型实现一个接口,接口中定义的所有方法和属性都是可以被拦截的。

    • 基于类型继承:如果目标类型是一个非Sealed类型,一个继承与它的代理类型会被动态生成。如果Interceptor被应用到目标类型的某个虚方法或者属性上,该成员会在生成的代理类中被重写,进而使Interceptor得以执行。这种拦截机制适合非Sealed类型,只有虚方法/属性能够被拦截。

  • 提供了针对属性的拦截支持:之前的版本支持针对方法的拦截,最新版本中提供了针对属性的拦截支持。我们可以选择将Interceptor应用到某个类型的属性上,也可以单独应用到该属性的Get或者Set方法上。

一、对基于Task的并行编程的支持

由于Dora.Interception将Dora.DynamicProxy作为默认的动态代理类型生成框架,所以不在依赖任何第三发框架,因此在编程会变得更加简单,现在我们来做一个简单的演示。在安装了最新版本的NuGet包Dora.Interception之后,我们可以按照 “约定” 的方式来定义如下这么一个简单的Interceptor类型。为了验证针对Task并行编程的支持,我们特意在拦截方法InvokeAsync中Delay了一秒钟。

public class FoobarInterceptor
{    
private InterceptDelegate _next;  

 public FoobarInterceptor(InterceptDelegate next){_next = next;}  

 public async Task InvokeAsync(InvocationContext context){Console.WriteLine("Interception task starts.");      
 await Task.Delay(1000);Console.WriteLine("Interception task completes.");  
     await _next(context);} }

我将Interceptor和Interceptor的注册特意区分开来,Interceptor的注册默认采用特性标注的形式来实现,为此我们为上面定义的FoobarInterceptor创建一个对应的特性类型FoobarAttribute。如下面的代码片段所示,FoobarAttribute派生于InterceptorAttribute,FoobarInterceptor在重写的Use方法中被构建,在构建过程中可以指定该Interceptor在整个Interceptor Chain的位置(Order)。

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Property)] 
public class FoobarAttribute : InterceptorAttribute
{    
public override void Use(IInterceptorChainBuilder builder){builder.Use<FoobarInterceptor>(this.Order);} }

接下来我们定义了简单的类型Demo来使用FoobarInterceptor,Demo实现了接口IDemo,FoobarAttribute标注在需要被拦截的方法InvokeAsync上。

public interface IDemo
{Task InvokeAsync();
}

public class Demo : IDemo {[Foobar]    
public Task InvokeAsync(){Console.WriteLine("Target method is invoked.");      
 return Task.CompletedTask;} }

由于Dora.Interception实现了与.NET Core的Dependency Injection的无缝集成,所以我们只需要采用我们熟悉的方式来提供服务实例就可以了。如下面的代码片段所示,我们将IDemo和Demo之间的映射关系注册到创建的ServiceCollection上之后,并没有调用BuildeServiceProvider方法,而是调用BuildInterceptableServiceProvider来创建提供服务的ServiceProvider。

class Program
{ 
static void Main(string[] args){        var demo = new ServiceCollection().AddSingleton<IDemo, Demo>() .BuildeInterceptableServiceProvider().GetRequiredService<IDemo>();  demo.InvokeAsync();Console.WriteLine("Continue...");Console.Read();} }

如下所示的是这段代码的执行结果,我们可以看到应用的FoobarInterceptor被正常执行,而且它完全是以异步的方式执行的。

二、基于虚方法的拦截

如果Demo没有实现任何的接口,并且它不是一个Sealed类型,它的虚方法和属性也是可以被拦截的。比如我们将Demo做了如下的改动。

public class Demo
{[Foobar]   
 public virtual Task InvokeAsync(){Console.WriteLine("Target method is invoked.");    
   return Task.CompletedTask;} }

所有Demo没有了接口实现,所以我们需要对服务注册代码做相应的修改。执行修后的代码,我们依然会得到相同的输出。

class Program
{    static void Main(string[] args){        var demo = new ServiceCollection().AddSingleton<Demo, Demo>() .BuildeInterceptableServiceProvider().GetRequiredService<Demo>();  demo.InvokeAsync();Console.WriteLine("Continue...");Console.Read();}
}

三、属性也可被拦截

对于上一版本来说,被拦截的成员仅限于普通的方法,最新的版本增加对属性的支持。如果一个Interceptor被直接应用到某个属性上,它实际上会被同时应用到该属性的Get和Set方法上。比如我们在Demo类型上添加一个Value属性,并在上面标准FoobarAttribute。

public class Demo
{[Foobar]    public virtual object Value { get; set; }
}

接下来我们按照如下的方式获取一个Demo对象,并调用其Value属性的Set和Get方法。

class Program
{   
 static void Main(string[] args){        var demo = new ServiceCollection().AddSingleton<Demo, Demo>().BuildInterceptableServiceProvider().GetRequiredService<Demo>();Console.WriteLine("Set...");demo.Value = new object();Console.WriteLine("Get...");      
 var value = demo.Value;Console.Read();} }

从如下的输出结果可以看出,我们注册到Value属性上的FoobarInterceptor在Get和Set方法被调用的时候都执行了一遍。

如果我们只需要在某个属性的Get或者Set方法上应用某个Interceptor,我们也可以作针对性的标注。在如下的代码片段中,我们将FoobarAttrbute标准到Get方法上。

public class Demo
{   
 public virtual object Value { [Foobar] get; set; } }

再次执行程序,我们会发现FoobarInterceptor仅仅在调用Value属性的Get方法时被执行了一次。

原文地址:https://www.cnblogs.com/artech/p/dora2-01.html


.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com

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

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

相关文章

欢乐纪中某A组赛【2019.7.8】

前言 你以为我是jzojjzojjzoj&#xff0c;其实我是GMojGMojGMoj哒 成绩 JJJ表示初中&#xff0c;HHH表示高中后面加的是几年级 上至222分XJQXJQXJQ,下至200ZZY200ZZY200ZZY都有我们SSLSSLSSL的人(滑稽) |RankRankRank|PersonPersonPerson|ScoreScoreScore|AAA|BBB|CCC| RankR…

Sentinel(十四)之控制台

转载自 Sentinel 控制台 1. 概述 Sentinel 提供一个轻量级的开源控制台&#xff0c;它提供机器发现以及健康情况管理、监控&#xff08;单机和集群&#xff09;&#xff0c;规则管理和推送的功能。这里&#xff0c;我们将会详细讲述如何通过简单的步骤就可以使用这些功能。 …

C# 这些年来受欢迎的特性

原文地址:http://www.dotnetcurry.com/csharp/1411/csharp-favorite-features在写这篇文章的时候&#xff0c;C# 已经有了 17 年的历史了&#xff0c;可以肯定地说它并没有去任何地方。C# 语言团队不断致力于开发新特性&#xff0c;改善开发人员的体验。在这篇文章中&#xff0…

Sentinel(十三)之动态规则扩展

转载自 动态规则扩展 规则 Sentinel 的理念是开发者只需要关注资源的定义&#xff0c;当资源定义成功后可以动态增加各种流控降级规则。Sentinel 提供两种方式修改规则&#xff1a; 通过 API 直接修改 (loadRules)通过 DataSource 适配不同数据源修改 手动通过 API 修改比较…

AspectCore动态代理中的拦截器详解(一)

前言在上一篇文章使用AspectCore动态代理中&#xff0c;简单说明了AspectCore.DynamicProxy的使用方式&#xff0c;由于介绍的比较浅显&#xff0c;也有不少同学留言询问拦截器的配置&#xff0c;那么在这篇文章中&#xff0c;我们来详细看一下AspectCore中的拦截器使用。两种配…

Actor-ES框架:Ray

并发1. 并发和并行并发&#xff1a;两个或多个任务在同一时间段内运行。关注点在任务分割。并行&#xff1a;两个或多个任务在同一时刻同时运行。关注点在同时执行。本文大多数情况下不会严格区分这两个概念&#xff0c;默认并发就是指并行机制下的并发。2. 好处随着多核处理器…

Sentinel(十五)之在生产环境中使用 Sentinel

转载自 在生产环境中使用 Sentinel 引言 Sentinel 目前已可用于生产环境&#xff0c;除了阿里巴巴以外&#xff0c;也有很多企业在生产环境中广泛使用 Sentinel。 生产环境的 Sentinel Dashboard 需要具备下面几个特性: 规则管理及推送&#xff0c;集中管理和推送规则。se…

Entity Framework Core 懒加载

众所周知在EF 6 及以前的版本中&#xff0c;是支持懒加载&#xff08;Lazy Loading&#xff09;的&#xff0c;可惜在EF Core 并不支持&#xff0c;必须使用Include方法来支持导航属性的数据加载。不过现在EF Core的开发团队打算恢复对这一功能的支持&#xff08;目前还未发布&…

Sentinel(十六)之AHAS Sentinel 控制台

转载自 AHAS Sentinel 控制台 AHAS Sentinel 是 Sentinel 的阿里云上版本&#xff0c;提供企业级的高可用防护服务&#xff0c;包括&#xff1a; 可靠的实时监控和历史秒级监控数据查询&#xff0c;包含 QPS、RT、load、CPU 使用率等指标&#xff0c;支持按照调用类型分类&a…

和各路巨佬の随机挑战3总结

第三次挑战\huge \texttt{\color{purple}第\color{blue}三\color{green}次\color{block}挑\color{red}战}第三次挑战 规则 随机挑取一蓝一紫一黑来做&#xff0c;拥有两次换题机会&#xff0c;若黑题是暂未学过的算法可以拥有无限次换题机会。 van♂van♂van♂成记录 过程 晚…

浅析Entity Framework Core2.0的日志记录与动态查询条件

一、 Entity Framework Core2.0的日志记录早在Entity Framework Core1.0 ,我们就使用相关的ILoggerProvider ILogger 这些基础接口类.来实现过日志记录.在Entity Framework Core2.0 估计是为了配合ASP.NET Core的日志.所以对这些接口进行了更进一步的包装,也弃用了一些接口和类…

Actor-ES框架:Ray--事件(Event)编写说明

Event作用&#xff1a;存储事件数据。IEventBaseK&#xff1a;是Actor的StateId的类型&#xff0c;可以是long、可以是string&#xff0c;Ray一般使用OGuid生成的字符串作为主键。编写Event继承IEventBase接口&#xff0c;Base部分如下&#xff1a; public string Id {…

设计模式之策略模式在地铁票价系统中的应用

引言设计模式是面向对象编程的一个非常精彩的部分。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性&#xff0c;它能帮助我们将应用组织成容易了解&#xff0c;容易维护&#xff0c;具有弹性的架构。本文通过一个简单的案例来讲述策略模式在地铁票价系…

Sentinel(十九)之主流框架的适配

转载自 主流框架的适配 注&#xff1a;适配模块仅提供相应适配功能&#xff0c;若希望接入 Sentinel 控制台&#xff0c;请务必参考 Sentinel 控制台文档。 云原生微服务体系 Spring Cloud Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案。Sentinel 与 Spring …

利用OCR文字识别+百度算法搜索,玩转冲顶大会、百万英雄、芝士超人等答题赢奖金游戏

【先上一张效果图】&#xff1a;一、原理&#xff1a;其实原理很简单&#xff1a;1.手机投屏到电脑&#xff1b;2.截取投屏画面的题目部分&#xff0c;进行识别&#xff0c;得到题目和三个答案&#xff1b;3.将答案按照一定的算法&#xff0c;进行搜索&#xff0c;得出推荐答案…

Sentinel(二十)之Envoy RLS Token Server

转载自 Envoy RLS Token Server Sentinel 提供了一个 Envoy Global Rate Limiting gRPC Service 的实现 sentinel-cluster-server-envoy-rls&#xff0c;借助集群限流 token server 来为 Envoy 服务网格提供集群流量控制的能力。 Note: You can refer to here for the Englis…

g4e基础篇#5 创建分支和保存代码

使用版本控制系统最常见的工作流程就是修改代码&#xff0c;保存代码&#xff0c;共享代码。Git提供了一个简单的3步工作流&#xff0c;让你方便的完成这些操作。1. 新建工作分支2. 提交更改3. 推送分支到中心存储库与团队成员共享Git 工作流按照以上3步操作&#xff0c;我们就…

P3952-时间复杂度【模拟】

正题 题目链接:https://www.luogu.org/problemnew/show/P3952 题目大意 比较复杂就直接给截图了 解题思路 开一个栈来维护序列&#xff0c;因为它保证合法的程序中一个变量不会相互嵌套所以就拿变量的字母当做每个循环的下标即可。然后对于输入的x,yx,yx,y有五种情况 xN,yN…

一步步部署基于Windows系统的Jenkins持续集成环境

如题&#xff1a;本文将介绍如何在Windows环境下运用Jenkins部署持续集成环境。之所以写本文&#xff0c;是因为在最近工作当中&#xff0c;学习使用Jenkins时&#xff0c;确实遇到了一些问题&#xff0c;而大多数教程文档都是基于Mac或是Linux平台。为此很是头疼&#xff0c;经…

Sentinel(二十二)之使用Nacos存储规则

转载自 Spring Cloud Alibaba基础教程&#xff1a;Sentinel使用Nacos存储规则 通过上一篇《使用Sentinel实现接口限流》的介绍&#xff0c;相信大家对Sentinel已经有了初步的认识。在Spring Cloud Alibaba的整合封装之下&#xff0c;接口限流这件事情可以非常轻易的整合到我们…