基于 Source Generators 做个 AOP 静态编织小实验
-0.1 系列目录
0. 前言
副标题:无价值人生记录.0:浪费 1000% 时间去做一个用来节省 1% 时间的“轮子玩具”(下:AOP实践2 Source Generators)
上接:用 Roslyn 做个 JIT 的 AOP https://xie.infoq.cn/article/93933c69ca17f31f81abe4441
作为第二篇,我们基于Source Generators做个AOP静态编织小实验。
内容安排如下:
source generators 是什么?
做个达到上篇Jit 一样的效果的demo
source generators还存在什么问题?
1. Source Generators 是什么?
1.1 核心目的
开启dotnet平台的编译时元编程功能,
让我们能在编译时期动态创建代码,
同时考虑IDE的集成,让体验更舒适。
官方文档:https://github.com/dotnet/roslyn/blob/master/docs/features/source-generators.md
展开我们思想的翅膀
我们能以此做各种事情:
生成实体json 等序列化器代码
AOP
接口定义生成httpclient调用代码
等等
如下是官方认为会受益的部分功能列表:
ASP.Net: Improve startup time
Blazor and Razor: Massively reduce tooling burden
Azure Functions: regex compilation during startup
Azure SDK
Resx file generation
Serializers
1.2 目前其设计和使用准则
允许开发者能在编译时动态创建添加新代码到我们程序里面
只能新增代码,不能修改已有代码
当无法生成源时,生成器应当产生诊断信息,通知用户问题所在。
可能访问其他文件非c#源代码文件。
无序运行模式,每个生成器都只能拥有相同的输入编译,即不能用其他生成器的生成结果进行再次生成。
生成器的运行类似于分析器。
2. 实验:代理模式的静态编织
2.1 创建一个Source Generators项目
2.2 创建SourceGenerator
需要继承 Microsoft.CodeAnalysis.ISourceGenerator
并通过[Generator]
标识启用
所以我们就可以做一个这样的代理生成器:
具体的代理代码生成逻辑:
可以看到和之前jit的代码非常相似
2.3 测试一下
2.3.1 新建测试项目
2.3.2 测试代码
输出结果:
5 + 10 = 15, but proxy is 16
cpu 和内存,自然完美:
完整的demo 放在 https://github.com/fs7744/AopDemoList
3. Source Generators 还有什么严重的缺陷呢?
3.1 不能引入其他程序集,比如nuget包
比如我们引入Newtonsoft.Json,就会造成如下编译异常:
System.IO.FileNotFoundException: 未能加载文件或程序集“Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed”或它的某一个依赖项。系统找不到指定的文件。
这就造成我们很难利用现有的包做各种事情,以及怎么把我们的代码生成器提供给别人使用了
有同学就这一点提了issue : https://github.com/dotnet/roslyn/issues/45060
感兴趣的同学可以去赞一赞
3.2 不能debug(其实我接受这点)
可以通过UT测试 debug的
3.3 生成结果不能查看
对使用生成器的人会比较麻烦,他不知道具体成什么样子了,特别是生成有错误的时候。
4.后记
毕竟该功能还是实验特性,距离完成还有一定距离,
不过这样可以让语言的发展。
文章最后还是求个赞吧:https://github.com/fs7744/Norns (更加完整的AOP demo)
版权声明: 本文为 InfoQ 作者【八苦-瞿昙】的原创文章。
原文链接:【http://xie.infoq.cn/article/3cc7e10552553702e23e65547】。文章转载请联系作者。
评论