NCoreCoder.Aop详解

于今天,功能终于完善度到比较满意的程度了

准备好好写一篇文章,而不是之前的流水账,分享一下最近这些天的踩坑


 

一开始AOP选的微软提供的DispatchProxy

关于这个,有大佬的文章,可以看看,了解一下

https://www.cnblogs.com/ElderJames/p/implement-simple-Aop-using-a-dotnet-core-library-System-Reflection-DispatchProxy.html

初步完成后,发现几个大问题,异步不支持,不支持构造器注入,代理类必须是继承DispatchProxy的公开类

我就想到我偶像Lemon大佬的著作AspectCore了,依稀记得是Emit构建的代理类

也有代码可以参考学习,那就开干,前后四天多的时间,终于完工

下面介绍一下我的AOP组件 NCoreCoder.Aop的使用以及高级应用


 

简单的使用NCoreCoder.Aop

NCoreCoder.Aop支持依赖注入,用依赖注入的方式完成代理类和接口的关联

支持.Net Core 3.0以及以下的依赖注入方式

示例

    public interface IMyClass{void TestVoid();int TestInt();Task TestAsync();Task<int> TestIntAsync();}[JitInject]internal class MyClass : IMyClass{public void TestVoid(){Console.WriteLine("TestVoid");}public int TestInt(){Console.WriteLine("TestInt");return 100;}public Task TestAsync(){Console.WriteLine("TestAsync");return Task.CompletedTask;}public Task<int> TestIntAsync(){Console.WriteLine("TestIntAsync");return Task.FromResult(100);}}

打上JitInject特性是证明这个类需要实现代理

这里就只是构建代理类,没有方法并走代理流程,代理支持 同步API、异步无返回值API、异步有返回值API

要拦截的方法,默认是继承JitAopAttribute,打特性方式完成拦截器注入

打在继承的实现类上

比如

    [AttributeUsage(AttributeTargets.Method)]internal class TestJitAttribute : JitAopAttribute{public override void Before(MethodReflector method, object instance, params object[] param){}public override void After(MethodReflector method, object instance, params object[] param){}public override Task BeforeAsync(MethodReflector method, object instance, params object[] param){return Task.CompletedTask;}public override Task AfterAsync(MethodReflector method, object instance, params object[] param){return Task.CompletedTask;}}

在需要拦截的方法上,打上TestJit即可

        [TestJit]public void TestVoid(){Console.WriteLine("TestVoid");}public int TestInt(){Console.WriteLine("TestInt");return 100;}public Task TestAsync(){Console.WriteLine("TestAsync");return Task.CompletedTask;}public Task<int> TestIntAsync(){Console.WriteLine("TestIntAsync");return Task.FromResult(100);}}

这样TestVoid方法就要走AOP流程了

Asp.Net Core 3.0以下

因为Asp.Net Core 3.0以下的Startup.ConfigService方法支持直接修改返回值变成IServiceProvider

所以在Asp.Net Core 3.0以下,依赖注入都是在Startup.ConfigService里面修改IServiceProvider到自定义的IServiceProvider完成替换依赖注入容器和流程的效果,比如Autofac

        public void ConfigureServices(IServiceCollection services){services.AddMvc();//略略略}

改为

        public IServiceProvider ConfigureServices(IServiceCollection services){services.AddMvc();//略略略service.AddSingleton<IMyClass, MyClass>();//修改Ioc容器流程return service.BuilderJit();}

Asp.Net Core 3.0

Asp.Net Core 3.0的替换依赖注入流程变了

无法再修改Startup.ConfigService返回值了,只要不是void,运行就抛出异常

查看的Program.CreateHostBuilder

        public static IHostBuilder CreateHostBuilder(string[] args) =>Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder =>{webBuilder.UseStartup<Startup>();});

改为

        public static IHostBuilder CreateHostBuilder(string[] args) =>Host.CreateDefaultBuilder(args).UseServiceProviderFactory(new JitServiceProviderFactory()) //新增.ConfigureWebHostDefaults(webBuilder =>{webBuilder.UseStartup<Startup>();});

这里可以保持原有依赖注入,也可以增加一个方法

        public void ConfigureContainer(JitAopBuilder builder){builder.Add<IMyClass, MyClass>(ServiceLifetime.Singleton);}

测试Aop

            var service = new ServiceCollection();service.AddSingleton<IMyClass, MyClass>();var serviceProvider = service.BuilderJit();TypeBuilderFactory.Instance.Save();var myclass = serviceProvider.GetRequiredService<IMyClass>();Task.Factory.StartNew(async () =>{myclass.TestVoid();var result1 = myclass.TestInt();await myclass.TestAsync();var result2 = await myclass.TestIntAsync();});Console.ReadLine();

我们运行看看myclass对象是什么~

 

不是原有的MyClass对象


高级扩展

我们现在如果要针对不同流程,而不是默认的Before->After

那么我们就需要自定义一个IAopActors了

我们默认的JitAopAttribute的流程就是一个默认DefaultAopActors

 

编写一个公开的类,继承自IAopActors

IAopActors接口如下

 

然后再接口上打上特性AopActorsAttribute

特性的构造参数是Type对应了自定义的AopActors的Type

    public class TestActors : IAopActors{public object Execute(AopContext context){throw new NotImplementedException();}public Task<TResult> ExecuteAsync<TResult>(AopContext context){throw new NotImplementedException();}public Task InvokeAsync(AopContext context){throw new NotImplementedException();}}
    [AopActors(typeof(TestActors))]public interface IMyClass{void TestVoid();int TestInt();Task TestAsync();Task<int> TestIntAsync();}

个人文笔不好,如有疑问,可以加“.Net应用程序框架交流” 群号386092459 欢迎到群里和我反馈Bug或者建议、交流Aop设计和Emit的知识

转载于:https://www.cnblogs.com/NCoreCoder/p/11597788.html

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

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

相关文章

主类网络号怎么算_一文了解网络文化经营许可证的审批范围

3月10日&#xff0c;北京市文化和旅游局发布《关于电商类、教育类、医疗类、培训类、金融类、旅游类、美食类、体育类、聊天类不需要申请办理的特别提示》(以下简称《特别提示》)。《特别提示》指出&#xff0c;随着互联网技术的快速发展&#xff0c;利用互联网从事文化经营活动…

idea命令行运行多个客户端_推荐一款神仙颜值的 Redis 客户端工具,开源啦

日常开发过程中&#xff0c;项目常常都会使用Redis来做缓存或者Session服务器&#xff0c;为了更直观方便&#xff0c;开发者常常会使用一些可视化工具&#xff0c;如 Redis Desktop Manager、Redis Clent等&#xff0c;但界面UI做得不尽人意&#xff0c;作为当今时代&#xff…

[html] 写html代码时,如果缺少了结束标签,你如何检测及如何预防?

[html] 写html代码时&#xff0c;如果缺少了结束标签&#xff0c;你如何检测及如何预防&#xff1f; 现在的编辑器如vscode就有语法检测 可以装一些代码自动完成插件预防此类事件个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但坚持一…

使用matlab判断CDMA接收码片

CDMA码分多址matlab计算 Contents 运算前工作原题表述:码片长度m发送序列为数据分析:运算前工作 clc clear all close all原题表述: ▇4个站的码片序列是a,b,c,d disp(▇4个站的码片序列为:) a[-1 -1 -1 1 1 -1 1 1] b[-1 -1 1 -1 1 1 1 -1] c[-1 1 -1 1 1 1 -1 -1] d[-1 1 -1 …

docker 挂载主机目录 -v 和 --mount区别

使用-v 时&#xff0c;如果宿主机上没有这个文件&#xff0c;也会自动创建&#xff0c; 但是如果使用--mount时&#xff0c;宿主机中没有这个文件会报错找不到这个文件&#xff0c;并创建失败 转载于:https://www.cnblogs.com/zhaojingyu/p/11599473.html

javascript二维数组转置_精通Excel数组公式010:认识数组函数:TRANSPOSE、MODE.MULT和TREND...

学习Excel技术&#xff0c;关注微信公众号&#xff1a;excelperfect数组函数是可以提供多个值的Excel内置函数。下面列出了8个Excel内置的数组函数&#xff1a;TRANSPOSE函数MODE.MULT函数(在Excel 2010中引入)TREND函数FREQUENCY函数LINEST函数MMULT函数MUNIT函数(在Excel 201…

linux python安装教程_Linux系统如何安装Python?新手教程

新手入门Python的第一步就是要在你的计算机上安装好Python。有些人可能要问了&#xff0c;Linux系统如何安装Python&#xff1f;本文为你准备了一份新手安装Python的教程&#xff0c;几乎是手把手教你如何操作&#xff0c;你只要尽量照着下面的教程说明&#xff0c;就能成功地在…

[html] 如何禁止html页面缓存?

[html] 如何禁止html页面缓存&#xff1f; 上面说清楚了如何禁止页面缓存&#xff0c;那我对这几个meta属性进行说明一下&#xff1a; Cache-Control表示缓存控制&#xff0c;no-cache&#xff0c;no-store&#xff0c;must-revalidate&#xff0c;都表示不缓存的意思。 不过&…

回调函数及使用方法

回调函数及使用方法回调函数说白了就是事件响应程序&#xff0c;Windows的每个消息可以理解为一个事件&#xff0c;事件的响应代码要由用户自己来定义。用户定义了事件响应的代码&#xff0c;但还要Windows知道这段代码的位置&#xff08;要不然Windows就不知道如何去调用&…

1-6docker数据共享与持久化

1、在 Docker 内部以及容器之间管理数据&#xff0c;在容器中管理数据主要有两种⽅式&#xff1a; 数据卷&#xff08;Data Volumes&#xff09; 挂载主机⽬录 (Bind mounts)2、数据卷 数据卷 是⼀个可供⼀个或多个容器使⽤的特殊⽬录&#xff0c;它绕过 UFS &#xff0c;可以提…

中yeti不能加载_第二十章_类的加载过程详解

类的加载过程详解概述在 Java 中数据类型分为基本数据类型和引用数据类型。基本数据类型由虚拟机预先定义&#xff0c;引用数据类型则需要进行类的加载按照 Java 虚拟机规范&#xff0c;从 Class 文件到加载到内存中的类&#xff0c;到类卸载出内存位置&#xff0c;它的整个生命…

泛型参数怎么new_泛型编程,你不知道?(基础篇)

关注“杜明c”&#xff0c;每天进步一点点&#xff01;我们学习C&#xff0c;就常常有人提起泛型编程&#xff0c;什么是泛型编程&#xff1f;我就给大家简单聊一聊。摘要-什么是泛型编程为什么使用泛型编程使用方法什么是泛型编程泛型编程&#xff0c;简而言之&#xff0c;就是…

flex画拓扑

FVT 基本的图表到复杂的交互图形和拓扑&#xff0c;提供数据管理、可是编码、动画、交互 Analytics&#xff1a;operators&#xff0c;为了计算和统计data Animate&#xff1a;创建动画的工具 Data&#xff1a;存储数据的模型 Display&#xff1a;继承flash.display Flex&#…

zabbix入门之添加监控项

zabbix入门之添加监控项 添加一个不带参数的监控项&#xff08;system.cpu.switches&#xff09; 进入“配置”-->“主机”选择某主机的“监控项” 选择创建监控项 键值后边的“选择”提供了大量的键值&#xff0c;带有[ ]的需要定义参数值&#xff0c;这里选择system.cpu.s…

[html] 网站如何自适应手机屏幕

[html] 网站如何自适应手机屏幕 一种是各种流式布局&#xff0c;另外就是简单粗暴&#xff0c;写两套&#xff0c;一套pc ,一套mobile ,根据设备标识来重定向不同的页面个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但坚持一定很酷。…

scratch跳一跳游戏脚本_cocos creator制作微信小游戏「跳一跳」

一、游戏的分析(之前没有接触过小游戏&#xff0c;制作的思维还停留在大型ARPG游戏大家共同协作的想法里&#xff0c;但是小游戏讲究小而全&#xff0c;大部分时间是一个人独立开发&#xff0c;所以需要迫使自己养成看到小游戏先拆分细化的思想)二、一些必要的参数台阶参数1: 设…

中boxplot函数的参数设置_如何在Python中生成图形和图表

在本章中&#xff0c;我们将学习如何在Python中生成图形和图表&#xff0c;同时将使用函数和面向对象的方法来可视化数据。Python中常用的一些可视化数据包括以下几种。Matplotlib。Seaborn。ggplot。Geoplotlib。Bokeh。Plotly。在本章中将使用Matplotlib可视化数据包。此外&a…

zabbix入门之监控MySQL

zabbix入门之监控MySQL 这里使用的是zabbix官方自带的MySQL监控模板。 首先确保在被监控主机安装zabbix-agent、zabbix-sender&#xff0c;并且将主机加入监控节点。具体操作请看zabbix添加主机&#xff1a;https://www.cnblogs.com/Smbands/p/11593593.html 修改zabbix自带的M…

[html] html中p标签内为何不能嵌套div标签?

[html] html中p标签内为何不能嵌套div标签&#xff1f; p 是行内 div 是块级个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但坚持一定很酷。欢迎大家一起讨论 主目录 与歌谣一起通关前端面试题

css清除浮动的几种方法_CSS 分享几种传统布局方法[上]

本章主要探讨 HTML5 中 CSS 早期所使用的传统布局&#xff0c;很多情况下&#xff0c;这些布局方式还是非常有用的。一&#xff0e;布局模型在早期没有平板和智能手机等移动设备大行其道的时期&#xff0c;Web 页面的设计主要是面向PC 端电脑分辨率展开的。这种分辨率比例比较单…