SourceGenerator 使用姿势(2):引入 scriban 模板引擎,简化生成代码,SourceGenerator.Template

发布时间 2023-06-12 16:00:38作者: ad313

SourceGenerator 挺有意思的,可以在编译时生成一些代码参与编译。只不过常规的使用需要在内部拼接字符串,每次修改还得重新打包,有点麻烦。

那么能不能引入模板引擎呢?当然是能!最终引入了 scriban 

 

这里简单讲一下为了引入模板踩的一些坑以及后续的问题。

首先引入 RazorEngineCore,开发的时候整的好好的,发布后就有一些莫名其妙的问题,这样找不到,那样没有。我发现 SourceGenerator 开发的时候是.net 环境,发布后是 .net core 环境。头发掉了三根,遂放弃之。

于是引入 scriban ,一顿操作行云流水,如丝般顺滑。

 

我的核心需求是去掉拼接字符串,引入模板。那么问题来了,SourceGenerator 只能读取当前程序集的文件,我编写了模板,那么模板怎么被读取呢?用什么方式塞入模板呢?

1、直接内置到工具库,把模板设为 “嵌入的资源”,在内部读取资源取到模板,然后其他项目引入这个程序集。这样的话想改模板也不方便。

2、直接内置到每一个 csproj 项目中。这样如果某个项目有5个csproj,那么模板得写五份。直接pass

3、专门写一个模板库,放置所有的模板。打包后给各个项目使用

 

这样就有了两个使用场景:

1、本地使用,那么直接项目内写模板,模板属性设置为 “C#分析器其他文件”,这样可以参与编译

2、需要多项目共享使用,那么就采用上面的方式3,专门写一个模板库,打包后给各个项目使用

 

SourceGenerator.Template 这个库中,支持上面两个使用场景引入模板

1、编写 Map.Json 注册模板。编写 .txt 模板内容

2、专门的模板库得以 Sg.Templates 结尾,内部读取这个库  Templates 里面的资源

 

其实就做了两件事:

1、扫描当前程序集的元数据,包含类型有 class、interface、struct、enum、method、property、attribute 等

2、加载定义的模板,挨个渲染输出文件。

怎么使用?

详情见 SourceGenerator.Template

 

大概是这样: