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. 阅读前,建 ...
随机推荐
- .NET Core使用AngleSharp网络数据采集
环境: vs2019 .net core 3.1 angleSharp winform 安装:angleSharp 有这么一本Python的书: <<Python 网络数据采集>&g ...
- Redis实例讲解
简介 Redis是一个key-value的nosql产品,和我们熟知的Memcached有些类似,但他存储value类型相对更加丰富,包括string(字符串),list(链表),set(集合),zs ...
- softmax、cross entropy和softmax loss学习笔记
之前做手写数字识别时,接触到softmax网络,知道其是全连接层,但没有搞清楚它的实现方式,今天学习Alexnet网络,又接触到了softmax,果断仔细研究研究,有了softmax,损失函数自然不可 ...
- Newbe.Claptrap 框架中为什么用 Claptrap 和 Minion 两个词?
Newbe.Claptrap 框架中为什么用 Claptrap 和 Minion 两个词?最近整理了一下项目的术语表.今天就谈谈为什么起了 Claptrap 和 Minion 两个名字. Claptr ...
- p46_IPv4地址
IP地址:全世界唯一的32位/4字节标识符,标识路由器主机的接口. IP地址::={<网络号>,<主机号>} 图中有6个子网 比如222.1.3.0是网络号,3是主机号,222 ...
- java valid 注解使用-java validation注解详解
注解 描述 @AssertFalse 带注解的元素必须为false,支持boolean/Boolean @AssertTrue 带注解的元素必须为true,支持boolean/Boolean @Dec ...
- Just test it!!软件测试测起来!!
(图片: josh@unsplash,字数:700,时间:1分钟) (一) 一切的软件质量保障活动,归根结底,就两种类型. 一种是基于代码执行的,一种是不基于代码执行的. 测试之于肉眼自查.静态检查. ...
- 在 Docker 搭建 Maven 私有库
在 Docker 搭建 Maven 私有库 小引 If you are developing software without a repository manager you are likely ...
- LeetCode 86 | 链表基础,一次遍历处理链表中所有符合条件的元素
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是LeetCode专题第53篇文章,我们一起来看LeetCode第86题,Partition List(链表归并). 本题的官方难度是M ...
- 图像增强 | CLAHE 限制对比度自适应直方图均衡化
1 基本概述 CLAHE是一个比较有意思的图像增强的方法,主要用在医学图像上面.之前的比赛中,用到了这个,但是对其算法原理不甚了解.在这里做一个复盘. CLAHE起到的作用简单来说就是增强图像的对比度 ...