NCoreCoder.Aop详解
于今天,功能终于完善度到比较满意的程度了
准备好好写一篇文章,而不是之前的流水账,分享一下最近这些天的踩坑
一开始AOP选的微软提供的DispatchProxy
关于这个,有大佬的文章,可以看看,了解一下
初步完成后,发现几个大问题,异步不支持,不支持构造器注入,代理类必须是继承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 ;
} public Task TestAsync()
{
Console.WriteLine("TestAsync"); return Task.CompletedTask;
} public Task<int> TestIntAsync()
{
Console.WriteLine("TestIntAsync"); return Task.FromResult();
}
}
打上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 ;
} public Task TestAsync()
{
Console.WriteLine("TestAsync"); return Task.CompletedTask;
} public Task<int> TestIntAsync()
{
Console.WriteLine("TestIntAsync"); return Task.FromResult();
}
}
这样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的知识
NCoreCoder.Aop详解的更多相关文章
- Spring4 AOP详解
Spring4 AOP详解 第一章Spring 快速入门并没有对Spring4 的 AOP 做太多的描述,是因为AOP切面编程概念不好理解.所以这章主要从三个方面详解AOP:AOP简介(了解),基于注 ...
- 【转载】Spring AOP详解 、 JDK动态代理、CGLib动态代理
Spring AOP详解 . JDK动态代理.CGLib动态代理 原文地址:https://www.cnblogs.com/kukudelaomao/p/5897893.html AOP是Aspec ...
- [Spring学习笔记 5 ] Spring AOP 详解1
知识点回顾:一.IOC容器---DI依赖注入:setter注入(属性注入)/构造子注入/字段注入(注解 )/接口注入 out Spring IOC容器的使用: A.完全使用XML文件来配置容器所要管理 ...
- AOP 详解
1. 需求:统计方法执行的性能情况(来源:<精通Spring 4.x>) // 性能监视类 PerformanceMonitor package com.noodles.proxy; pu ...
- Spring AOP详解(转载)所需要的包
上一篇文章中,<Spring Aop详解(转载)>里的代码都可以运行,只是包比较多,中间缺少了几个相应的包,根据报错,几经百度搜索,终于补全了所有包. 截图如下: 在主测试类里面,有人怀疑 ...
- Spring AOP详解及简单应用
Spring AOP详解 一.前言 在以前的项目中,很少去关注spring aop的具体实现与理论,只是简单了解了一下什么是aop具体怎么用,看到了一篇博文写得还不错,就转载来学习一下,博文地址: ...
- 转:Spring AOP详解
转:Spring AOP详解 一.前言 在以前的项目中,很少去关注spring aop的具体实现与理论,只是简单了解了一下什么是aop具体怎么用,看到了一篇博文写得还不错,就转载来学习一下,博文地址: ...
- Spring全家桶——SpringBoot之AOP详解
Spring全家桶--SpringBoot之AOP详解 面向方面编程(AOP)通过提供另一种思考程序结构的方式来补充面向对象编程(OOP). OOP中模块化的关键单元是类,而在AOP中,模块化单元是方 ...
- Spring Aop 详解二
这是Spring Aop的第二篇,案例代码很详解,可以查看https://gitee.com/haimama/java-study/tree/master/spring-aop-demo. 阅读前,建 ...
随机推荐
- 零拷贝(Zero-copy) 浅析及其应用
相信大家都有过面经历,如果跟面试官聊到了操作系统,聊到了文件操作,可能会问你普通的文件读写流程,它有什么缺点,你知道有什么改进的措施.我们经常听说 零拷贝,每次可能只是背诵一些面试要点就过去了,今天我 ...
- Redis实例讲解
简介 Redis是一个key-value的nosql产品,和我们熟知的Memcached有些类似,但他存储value类型相对更加丰富,包括string(字符串),list(链表),set(集合),zs ...
- scala 数据结构(六):映射 Map
1 映射 Map-基本介绍 Scala中的Map介绍 1) Scala中的Map 和Java类似,也是一个散列表,它存储的内容也是键值对(key-value)映射,Scala中不可变的Map是有序的, ...
- 爬虫06 /scrapy框架
爬虫06 /scrapy框架 目录 爬虫06 /scrapy框架 1. scrapy概述/安装 2. 基本使用 1. 创建工程 2. 数据分析 3. 持久化存储 3. 全栈数据的爬取 4. 五大核心组 ...
- 文件上传漏洞fuzz字典生成脚本小工具分享
前言 学习xss的时候翻阅资料发现了一个文件上传漏洞fuzz字典生成脚本小工具,试了试还不错,分享一下 配置 需要python2环境 工具地址:https://github.com/c0ny1/upl ...
- js 分享QQ、QQ空间、微信、微博
//分享QQ好友 function qq(title,url,pic) { var p = { url: 'http://test.qicheyitiao.com',/*获取URL,可加上来自分享到Q ...
- Java常用API(Math类)
Java常用API(Math类) Math类的作用 java.lang.Math 类包含用于执行基本数学运算的方法,如初等指数.对数.平方根和三角函数.类似这样的工具 类,其所有方法均为静态方法,并且 ...
- 拦截器(Interceptor)中的invocation.invoke()是什么意思?
拦截器(Interceptor)中的invocation.invoke()是什么意思? 最佳答案: invocation.invoke() 就是通知struts2接着干下面的事情 比如 调用下一个拦截 ...
- 修改map中原来的各种Key
简单描述: 做数据迁移的时候,需要展示数据库的字段信息,但是我发现 Oracle的sql查询到的结果 出来默认是大写的 和 前端vue的参数小写开头+驼峰 不太一样 所以后台取到的数据都是是引用Lis ...
- 大一寒假我在一个oj网站只刷了这些题从此入门了绝大部分通用算法
如果你想入门算法,那么我这篇文章也许可以帮到你. 先说点题外话.这是在一个不冷不热的寒假,照理来说寒假应该很冷,但这个寒假是真的舒服.这样舒服的寒假学习似乎是一件不可能的事情,所以我继续我的游戏生涯, ...