SlideShare a Scribd company logo
探索 .NET 新世界
.NET Conf
The Journey of
Source Generator
Roberson Liou
2
關於我
• 手沖咖啡科技宅
• Backend Engineer
• Microsoft MVP(2020-2021)
• twMVC 核心成員
• DevOps Taiwan 志工
• 工程良田的小球場
p.3
Outline
• Introduce Source Generator
• How to use Source Generator?
• Demo
4
Introduce Source Generator
What’s the Source Generator?
• .NET 5 釋出的一個 Roslyn 新項目
• 在編譯階段產生程式碼
• 附加至最後的編譯結果
• Compile-time Meta Programing
• Meta 來源:SyntaxTree、File、Config
p.6
What CAN it do?
• 取得 Roslyn 編譯後的 Compilation
• 取得外部專案的附加檔案
• 取得 Config 的自定義資訊
• 輸出實體檔案到指定資料夾中
• 與 IDE整合輸出診斷資訊
p.7
What can NOT it do?
• 不能修改原本的程式碼
• 無法達到 AOP 效果
• 可以有多個 Generator,但彼此間不能相互參考
• 不能產生 C# 程式碼以外的檔案
p.8Source Generators: Allow embedding of files other than source #49935
Lifecycle - C# Compilation
C# code
Program.cs
Compile IL Code
.dll .exe
p.9
Lifecycle - Invoke Source Generator
C# code
Program.cs
Compile IL Code
.dll .exe
Invoke
Source
Generator
p.10
le
Lifecycle - Source Generator
IL
Invoke
Source
Generator
p.11
Source Generator
step of compilation
Add generated
code to compilation
Analyze
source code
Generate new
source code
Invoke Source Generator
Source Generator
Compile
Lifecycle - Overall
IL Code
.dll .exe
Invoke
Source
Generator
p.12
Source Generator
step of compilation
Add generated
code to compilation
Analyze
source code
Generate new
source code
Invoke Source Generator
Source Generator
C# code
Program.cs
Benefits
• 將 Runtime reflection 轉為 Compile-time
• 提升效能
• 處理序列化檔案
• .csv / .xml
• 擴增原始程式碼
• partial class / partial method
p.13
How to use
Source Generator?
執行環境
• .NET 5 (SDK 5.0.100)
• Visual Studio 2019 (16.8.0+)
• JetBrains Rider 2020.3 / EAP 10
p.15
Visual Studio 2019
• 需手動叫用 Debugger 偵錯
• 可查看產生的程式碼定義
• 會自動標註 auto-generated
• 重新建置後會有快取問題,要重開 VS 才能解決
p.16
JetBrains Rider EAP 10 / 2020.3
• 需透過 VS 2019 才能偵錯
• 可查看產生的程式碼定義
• 不會自動標註 auto-generated
• 重新建置後即可查看新的建置程式碼
p.17
Generator 起手式
• 建立 .NET Standard 2.0 函式庫
• 安裝套件
• Microsoft.CodeAnalysis.CSharp (v3.8.0)
• Microsoft.CodeAnalysis.Analyzers (v3.3.1)
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp"
Version="3.8.0" />
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers"
Version="3.3.1" />
</ItemGroup>
p.18
在專案中啟用 Generator
• 加入專案參考,需額外加入以下兩個屬性。
• OutputItemType="Analyzer"
• ReferenceOutputAssembly="false"
• 使用 NuGet 套件安裝 Generator 則無須另外設定。
<ItemGroup>
<ProjectReference Include="..MyGeneratorLibMyGeneratorLib.csproj"
OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
</ItemGroup>
p.19
Generator 核心成員
• ISourceGenerator
• GeneratorAttribute
• GeneratorInitializationContext
• GeneratorExecutionContext
• ISyntaxReceiver
p.20
必要實作
初始
執行
篩選 Syntax
實作 Generator
• 於類別掛上 [Generator]
• 實作 ISourceGenerator
• Initialize
• Execute
[Generator]
public class MyGenerator : ISourceGenerator
{
public void Initialize(GeneratorInitializationContext context){}
public void Execute(GeneratorExecutionContext context){}
}
p.21
Generator - Initialize
• 主要成員為 GeneratorInitializationContext
• context 中具有一個 CancellationToken
• RegisterForSyntaxNotifications 可用來註冊 ISyntaxReceiver
public void Initialize
(GeneratorInitializationContext context)
{
context.RegisterForSyntaxNotifications(
() => new MySyntaxReceiver());
}
p.22
Example - MySyntaxReceiver
public class MySyntaxReceiver : ISyntaxReceiver
{
public ClassDeclarationSyntax MyClassSyntax { get; private set; }
public void OnVisitSyntaxNode(SyntaxNode syntaxNode)
{
if (syntaxNode is ClassDeclarationSyntax classSyntax)
{
if (classSyntax.Identifier.ValueText == "MyClass")
{
MyClassSyntax = classSyntax;
}
}
}
}
p.23[ Source Generator ] 使用 SyntaxReceiver 快速篩選關注的 Syntax 資訊
Generator - Execute
• 主要成員為 GeneratorExecutionContext
• context 中具有一個 CancellationToken
• 從 context 取出各種 meta
• 依邏輯產生程式碼字串,並加到最後的編譯結果
• 向 IDE 回報診斷資訊
p.24
Generator - AddSource
• 將要產生的程式碼加到最後的編譯結果
public void Execute(GeneratorExecutionContext context)
{
var codeText = @"namespace Sample { public class HelloWorld
{ public void Say() => Console.WriteLine(""Hello World""); }}}";
context.AddSource("HelloWorld", SourceText.From(codeText, Encoding.
UTF8));
}
p.25
Generator - CancellationToken
• 在 Initial 及 Execute 中都有提供
• Generator 會在 IDE 的背景執行
• IDE 提供即時的 Intellisence
• 在檔案內容變更時 Generator 會被呼叫
• 提供 IDE 一個取消 Generator 執行的機制
• 可降低 CPU 使用率
p.26[ref] When will generator be canceled?
Example - CancellationToken
p.27[ref] When will generator be canceled?
[Generator]
public class MyGenerator : ISourceGenerator
{
public void Initialize(GeneratorInitializationContext context)
{
if (!context.CancellationToken.IsCancellationRequested)
{
}
}
public void Execute(GeneratorExecutionContext context)
{
if (!context.CancellationToken.IsCancellationRequested)
{
}
}
}
如何偵錯 Generator
• 目前無法與 IDE 自動整合
• 必須透過程式手動叫用偵錯器
• 必須手動選擇偵錯執行的 IDE 視窗
public void Initialize
(GeneratorInitializationContext context)
{
System.Diagnostics.Debugger.Launch();
}
p.28
Getting Advanced
– How to retrieve Metadata?
Meta 可以從哪裡來?
• Compilation
• SyntaxTree, SemanticModel
• SyntaxRecevier
• AddtionalFiles
• AnalyzerConfigOptions
p.30
取得 Syntax 資訊
• 從 context.Compilation 拿到首次編譯的結果
• 主要對象是 Roslyn 的 Syntax API
• 取得 BotAttribute 的 AttributeSyntax
var syntaxNodes = compilation
.SyntaxTrees.SelectMany(s => s.GetRoot().DescendantNodes());
var attributeSyntaxs = syntaxNodes
.Where((d) => d.IsKind(SyntaxKind.Attribute)).OfType<AttributeSyntax>();
var botAttributeSyntax = attributeSyntaxs.
FirstOrDefault(x => x.Name.ToString() == "Bot");
p.31
取得 SyntaxReceiver 資訊
• 從 context 取得 SyntaxRecevier 後再做轉型
public void Execute(GeneratorExecutionContext context)
{
MyClassSyntaxReceiver receiver =
(MyClassSyntaxReceiver) context.SyntaxReceiver;
var myClassSyntax = receiver.MyClassSyntax;
}
Additional file transformationp.32
存取附加檔案資訊
• 必須手動於 .csproj 裡面宣告
• 可於 xml 標籤內自訂屬性資訊
• 須明確標記為 CompilerVisibleItemMetadata
<ItemGroup>
<AdditionalFiles Include="Cars.csv" CacheObjects="true" />
<CompilerVisibleItemMetadata Include="AdditionalFiles"
MetadataName="CacheObjects" />
</ItemGroup>
Additional file transformationp.33
回報診斷訊息
• 使用 ReportDiagnostic 向 IDE 回報診斷訊息
Context.ReportDiagnostic(Diagnostic.Create(
new DiagnosticDescriptor("MYERR001", "TestDiagnostic",
$"Here is a error.", "source generator",
DiagnosticSeverity.Error, true), Location.None));
[ref] Issue Diagnostics p.34
將產生的程式輸出為實體檔案
• EmitCompilerGeneratedFiles:允許輸出檔案
• CompilerGeneratedFilesOutputPath:指定輸出路徑
<PropertyGroup>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<CompilerGeneratedFilesOutputPath>
$(BaseIntermediateOutputPath)GeneratedFiles
</CompilerGeneratedFilesOutputPath>
</PropertyGroup>
p.35
如何打包成 NuGet package
• 設定 GeneratePackageOnBuild 為 true
• 設定 IncludeBuildOutput 為 false
• 設定 Generator 用的套件標示為 PrivateAssets="all"
• 設定 Generator 打包路徑於 analyzer 目錄下
[ref] Package a generator as a NuGet package p.36
如何打包成 NuGet package
<PropertyGroup>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<IncludeBuildOutput>false</IncludeBuildOutput>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp"
Version="3.8.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers"
Version="3.3.1" PrivateAssets="all" />
<!-- 將 Generator 打包路徑指定在 analyzer 目錄下 -->
<None Include="$(OutputPath)$(AssemblyName).dll" Pack="true"
PackagePath="analyzers/dotnet/cs" Visible="false" />
</ItemGroup>
[ref] Package a generator as a NuGet package p.37
參考外部的 NuGet 套件
• 當套件用途為供 Generator 執行過程用時
• 必須設定 PrivateAssets 及 GeneratePathProperty 屬性
• 必須額外將 dll 打包到指定的 analyzer 目錄底下
• 套件名稱要改為 Pkg{PACKAGE_NAME}
• 遇到點(.)要改為底線 ( _ )
• EX: Newtonfost.Json => PkgNewtonsoft_Json
[ref] Use functionality from NuGet packages p.38
Example – Pack Newtonsoft.Json
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="12.0.1"
PrivateAssets="all" GeneratePathProperty="true" />
<!-- 將套件 .dll 打包路徑指定在 analyzer 目錄下 -->
<None Include="$(PkgNewtonsoft_Json)libnetstandard2.0*.dll"
Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
</ItemGroup>
[ref] Use functionality from NuGet packages p.39
使用案例介紹
• Hello World
• DotNetBot
• DataBuilder
• CSVToList
• Mapper
p.40
https://github.com/robersonliou/SourceGeneratorJourney
結語
• 尚未與 IDE 偵錯完全整合
• 繞來繞去最後還是得搞 Roslyn
• 寫起來很煩,用起來很爽
• 若要收納為團隊用途,請寫說明文件
• 期待 .NET 6 會推出更兇猛的功能
p.41
補充 – Syntax 分析工具介紹
• SyntaxViewer (Visual Studio 2019 內建)
• SharpLab
• LinqPad
p.42
補充 – 使用案例
• DataBuilder
• StrongInject
• InlineMapper
• 官方 Roslyn-SDK 範例
p.43
References (Microsoft)
• Introducing C# Source Generators
• New C# Source Generator Samples
• Source Generators Cookbook
• Source Generators
p.44
References (Other)
• Generating Code in C#
• Source Generators in .NET 5 with ReSharper
• Auto generate builders using Source Generator in .NET 5
• Thinking beyond Roslyn source generators and aspect-oriented
programming (postsharp)
p.45
 .NET 5.0 released today!
 Major releases every year in November
 LTS for even numbered releases
 Predictable schedule, minor releases as needed
.NET Schedule
Nov 2020
.NET 5.0
Nov 2021
.NET 6.0
LTS
Nov 2022
.NET 7.0
Nov 2023
.NET 8.0
LTS
Nov 2024
.NET 9.0
特別感謝

More Related Content

What's hot

[Agile Tour Hsinchu 2019] Our practice in the DevOps Process for Manufacture ...
[Agile Tour Hsinchu 2019] Our practice in the DevOps Process for Manufacture ...[Agile Tour Hsinchu 2019] Our practice in the DevOps Process for Manufacture ...
[Agile Tour Hsinchu 2019] Our practice in the DevOps Process for Manufacture ...
Edward Kuo
 
VSCode Remote Development 介紹
VSCode Remote Development 介紹VSCode Remote Development 介紹
VSCode Remote Development 介紹
Philip Zheng
 
[2021 .NET Conf]善用 Azure Monitor 服務打造 DevOps 監控一環
[2021 .NET Conf]善用 Azure Monitor 服務打造 DevOps 監控一環[2021 .NET Conf]善用 Azure Monitor 服務打造 DevOps 監控一環
[2021 .NET Conf]善用 Azure Monitor 服務打造 DevOps 監控一環
Edward Kuo
 
我們與Azure DevOps的距離
我們與Azure DevOps的距離我們與Azure DevOps的距離
我們與Azure DevOps的距離
Edward Kuo
 
[Study4.TW .NET Conf 2019]看,用 Azure 建立工業 4.0 的第一步
[Study4.TW .NET Conf 2019]看,用 Azure 建立工業 4.0 的第一步[Study4.TW .NET Conf 2019]看,用 Azure 建立工業 4.0 的第一步
[Study4.TW .NET Conf 2019]看,用 Azure 建立工業 4.0 的第一步
Edward Kuo
 
Reactive application with akka.NET & .NET Core
Reactive application with akka.NET & .NET CoreReactive application with akka.NET & .NET Core
Reactive application with akka.NET & .NET Core
Chen-Tien Tsai
 
VSCode Remote Development
VSCode Remote DevelopmentVSCode Remote Development
VSCode Remote Development
Philip Zheng
 
容器驅動開發 - .NET Conf 2017 @ 台中
容器驅動開發 - .NET Conf 2017 @ 台中容器驅動開發 - .NET Conf 2017 @ 台中
容器驅動開發 - .NET Conf 2017 @ 台中
Andrew Wu
 
02 azure devops pipeline - build
02 azure devops pipeline - build02 azure devops pipeline - build
02 azure devops pipeline - build
Alan Tsai
 
极速 Angular 开发:效能调校技巧 (ngChina 2019)
极速 Angular 开发:效能调校技巧 (ngChina 2019)极速 Angular 开发:效能调校技巧 (ngChina 2019)
极速 Angular 开发:效能调校技巧 (ngChina 2019)
Will Huang
 
微服務對IT人員的衝擊
微服務對IT人員的衝擊微服務對IT人員的衝擊
微服務對IT人員的衝擊
Philip Zheng
 
@Connect(); microsoft visual studio vnext & azure
@Connect(); microsoft visual studio vnext & azure@Connect(); microsoft visual studio vnext & azure
@Connect(); microsoft visual studio vnext & azure
Bruce Chen
 
03 azure devops pipeline - release
03 azure devops pipeline - release03 azure devops pipeline - release
03 azure devops pipeline - release
Alan Tsai
 
容器與 Gitlab CI 應用
容器與 Gitlab CI 應用容器與 Gitlab CI 應用
容器與 Gitlab CI 應用
Philip Zheng
 
twMVC#23 | 快速上手 Azure Functions
twMVC#23 | 快速上手 Azure FunctionstwMVC#23 | 快速上手 Azure Functions
twMVC#23 | 快速上手 Azure Functions
twMVC
 
Visual Studio 開發密技大補帖 | Study4.TW 2021 小聚#2
Visual Studio 開發密技大補帖 | Study4.TW 2021 小聚#2Visual Studio 開發密技大補帖 | Study4.TW 2021 小聚#2
Visual Studio 開發密技大補帖 | Study4.TW 2021 小聚#2
Alan Tsai
 
[2021 DevDays]Microsoft Teams 整合 Azure DevOps之實務應用
[2021 DevDays]Microsoft Teams 整合 Azure DevOps之實務應用[2021 DevDays]Microsoft Teams 整合 Azure DevOps之實務應用
[2021 DevDays]Microsoft Teams 整合 Azure DevOps之實務應用
Edward Kuo
 
認識程式交易
認識程式交易認識程式交易
認識程式交易
Philip Zheng
 
Microsoft Tech Summit 2017 - 制造业运用微软研发云实现云到端的 DevOps 架构
Microsoft Tech Summit  2017 - 制造业运用微软研发云实现云到端的 DevOps 架构Microsoft Tech Summit  2017 - 制造业运用微软研发云实现云到端的 DevOps 架构
Microsoft Tech Summit 2017 - 制造业运用微软研发云实现云到端的 DevOps 架构
Edward Kuo
 
不會 Javascript 沒關係,用 Blazor 來解決前端需求 - 成為 Full Stack .NET 開發者吧 - .NET Conf 2020...
不會 Javascript 沒關係,用 Blazor 來解決前端需求 - 成為 Full Stack .NET 開發者吧 - .NET Conf 2020...不會 Javascript 沒關係,用 Blazor 來解決前端需求 - 成為 Full Stack .NET 開發者吧 - .NET Conf 2020...
不會 Javascript 沒關係,用 Blazor 來解決前端需求 - 成為 Full Stack .NET 開發者吧 - .NET Conf 2020...
Alan Tsai
 

What's hot (20)

[Agile Tour Hsinchu 2019] Our practice in the DevOps Process for Manufacture ...
[Agile Tour Hsinchu 2019] Our practice in the DevOps Process for Manufacture ...[Agile Tour Hsinchu 2019] Our practice in the DevOps Process for Manufacture ...
[Agile Tour Hsinchu 2019] Our practice in the DevOps Process for Manufacture ...
 
VSCode Remote Development 介紹
VSCode Remote Development 介紹VSCode Remote Development 介紹
VSCode Remote Development 介紹
 
[2021 .NET Conf]善用 Azure Monitor 服務打造 DevOps 監控一環
[2021 .NET Conf]善用 Azure Monitor 服務打造 DevOps 監控一環[2021 .NET Conf]善用 Azure Monitor 服務打造 DevOps 監控一環
[2021 .NET Conf]善用 Azure Monitor 服務打造 DevOps 監控一環
 
我們與Azure DevOps的距離
我們與Azure DevOps的距離我們與Azure DevOps的距離
我們與Azure DevOps的距離
 
[Study4.TW .NET Conf 2019]看,用 Azure 建立工業 4.0 的第一步
[Study4.TW .NET Conf 2019]看,用 Azure 建立工業 4.0 的第一步[Study4.TW .NET Conf 2019]看,用 Azure 建立工業 4.0 的第一步
[Study4.TW .NET Conf 2019]看,用 Azure 建立工業 4.0 的第一步
 
Reactive application with akka.NET & .NET Core
Reactive application with akka.NET & .NET CoreReactive application with akka.NET & .NET Core
Reactive application with akka.NET & .NET Core
 
VSCode Remote Development
VSCode Remote DevelopmentVSCode Remote Development
VSCode Remote Development
 
容器驅動開發 - .NET Conf 2017 @ 台中
容器驅動開發 - .NET Conf 2017 @ 台中容器驅動開發 - .NET Conf 2017 @ 台中
容器驅動開發 - .NET Conf 2017 @ 台中
 
02 azure devops pipeline - build
02 azure devops pipeline - build02 azure devops pipeline - build
02 azure devops pipeline - build
 
极速 Angular 开发:效能调校技巧 (ngChina 2019)
极速 Angular 开发:效能调校技巧 (ngChina 2019)极速 Angular 开发:效能调校技巧 (ngChina 2019)
极速 Angular 开发:效能调校技巧 (ngChina 2019)
 
微服務對IT人員的衝擊
微服務對IT人員的衝擊微服務對IT人員的衝擊
微服務對IT人員的衝擊
 
@Connect(); microsoft visual studio vnext & azure
@Connect(); microsoft visual studio vnext & azure@Connect(); microsoft visual studio vnext & azure
@Connect(); microsoft visual studio vnext & azure
 
03 azure devops pipeline - release
03 azure devops pipeline - release03 azure devops pipeline - release
03 azure devops pipeline - release
 
容器與 Gitlab CI 應用
容器與 Gitlab CI 應用容器與 Gitlab CI 應用
容器與 Gitlab CI 應用
 
twMVC#23 | 快速上手 Azure Functions
twMVC#23 | 快速上手 Azure FunctionstwMVC#23 | 快速上手 Azure Functions
twMVC#23 | 快速上手 Azure Functions
 
Visual Studio 開發密技大補帖 | Study4.TW 2021 小聚#2
Visual Studio 開發密技大補帖 | Study4.TW 2021 小聚#2Visual Studio 開發密技大補帖 | Study4.TW 2021 小聚#2
Visual Studio 開發密技大補帖 | Study4.TW 2021 小聚#2
 
[2021 DevDays]Microsoft Teams 整合 Azure DevOps之實務應用
[2021 DevDays]Microsoft Teams 整合 Azure DevOps之實務應用[2021 DevDays]Microsoft Teams 整合 Azure DevOps之實務應用
[2021 DevDays]Microsoft Teams 整合 Azure DevOps之實務應用
 
認識程式交易
認識程式交易認識程式交易
認識程式交易
 
Microsoft Tech Summit 2017 - 制造业运用微软研发云实现云到端的 DevOps 架构
Microsoft Tech Summit  2017 - 制造业运用微软研发云实现云到端的 DevOps 架构Microsoft Tech Summit  2017 - 制造业运用微软研发云实现云到端的 DevOps 架构
Microsoft Tech Summit 2017 - 制造业运用微软研发云实现云到端的 DevOps 架构
 
不會 Javascript 沒關係,用 Blazor 來解決前端需求 - 成為 Full Stack .NET 開發者吧 - .NET Conf 2020...
不會 Javascript 沒關係,用 Blazor 來解決前端需求 - 成為 Full Stack .NET 開發者吧 - .NET Conf 2020...不會 Javascript 沒關係,用 Blazor 來解決前端需求 - 成為 Full Stack .NET 開發者吧 - .NET Conf 2020...
不會 Javascript 沒關係,用 Blazor 來解決前端需求 - 成為 Full Stack .NET 開發者吧 - .NET Conf 2020...
 

Similar to The Journey of Source Generator

twMVC#41 The journey of source generator
twMVC#41 The journey of source generatortwMVC#41 The journey of source generator
twMVC#41 The journey of source generator
twMVC
 
Introduction to MVC of CodeIgniter 2.1.x
Introduction to MVC of CodeIgniter 2.1.xIntroduction to MVC of CodeIgniter 2.1.x
Introduction to MVC of CodeIgniter 2.1.x
Bo-Yi Wu
 
Python 于 webgame 的应用
Python 于 webgame 的应用Python 于 webgame 的应用
Python 于 webgame 的应用
勇浩 赖
 
Web development with zend framework
Web development with zend frameworkWeb development with zend framework
Web development with zend frameworkthinkinlamp
 
Kindeditor设计思路v2
Kindeditor设计思路v2Kindeditor设计思路v2
Kindeditor设计思路v2luolonghao
 
Kind editor设计思路
Kind editor设计思路Kind editor设计思路
Kind editor设计思路taobao.com
 
Kindeditor 设计思路
Kindeditor 设计思路Kindeditor 设计思路
Kindeditor 设计思路luolonghao
 
Spring 2.x 中文
Spring 2.x 中文Spring 2.x 中文
Spring 2.x 中文Guo Albert
 
Template mb-kao
Template mb-kaoTemplate mb-kao
Template mb-kaoxwcoder
 
Linux binary Exploitation - Basic knowledge
Linux binary Exploitation - Basic knowledgeLinux binary Exploitation - Basic knowledge
Linux binary Exploitation - Basic knowledge
Angel Boy
 
Django development
Django developmentDjango development
Django developmentloveyudu
 
Software Engineer Talk
Software Engineer TalkSoftware Engineer Talk
Software Engineer Talk
Larry Cai
 
千呼萬喚始出來的 Java SE 7
千呼萬喚始出來的 Java SE 7千呼萬喚始出來的 Java SE 7
千呼萬喚始出來的 Java SE 7
Justin Lin
 
基于 FRIDA 的全平台逆向分析
基于 FRIDA 的全平台逆向分析基于 FRIDA 的全平台逆向分析
基于 FRIDA 的全平台逆向分析
CC
 
Introduction to CodeIgniter
Introduction to CodeIgniterIntroduction to CodeIgniter
Introduction to CodeIgniterChun-Kai Wang
 
Django step0
Django step0Django step0
Django step0
永昇 陳
 
2023-netconf-deploy-azure-function-with-KEDA-on-aks
2023-netconf-deploy-azure-function-with-KEDA-on-aks2023-netconf-deploy-azure-function-with-KEDA-on-aks
2023-netconf-deploy-azure-function-with-KEDA-on-aks
Roberson Liou
 
钱宝坤:多浏览器集成的JavaScript单元测试工具
钱宝坤:多浏览器集成的JavaScript单元测试工具钱宝坤:多浏览器集成的JavaScript单元测试工具
钱宝坤:多浏览器集成的JavaScript单元测试工具taobao.com
 
Java Build Tool course in 2011
Java Build Tool course in 2011Java Build Tool course in 2011
Java Build Tool course in 2011Ching Yi Chan
 

Similar to The Journey of Source Generator (20)

twMVC#41 The journey of source generator
twMVC#41 The journey of source generatortwMVC#41 The journey of source generator
twMVC#41 The journey of source generator
 
Introduction to MVC of CodeIgniter 2.1.x
Introduction to MVC of CodeIgniter 2.1.xIntroduction to MVC of CodeIgniter 2.1.x
Introduction to MVC of CodeIgniter 2.1.x
 
Python 于 webgame 的应用
Python 于 webgame 的应用Python 于 webgame 的应用
Python 于 webgame 的应用
 
Web development with zend framework
Web development with zend frameworkWeb development with zend framework
Web development with zend framework
 
Kindeditor设计思路v2
Kindeditor设计思路v2Kindeditor设计思路v2
Kindeditor设计思路v2
 
Kind editor设计思路
Kind editor设计思路Kind editor设计思路
Kind editor设计思路
 
Kindeditor 设计思路
Kindeditor 设计思路Kindeditor 设计思路
Kindeditor 设计思路
 
Spring 2.x 中文
Spring 2.x 中文Spring 2.x 中文
Spring 2.x 中文
 
Template mb-kao
Template mb-kaoTemplate mb-kao
Template mb-kao
 
Linux binary Exploitation - Basic knowledge
Linux binary Exploitation - Basic knowledgeLinux binary Exploitation - Basic knowledge
Linux binary Exploitation - Basic knowledge
 
Berserk js
Berserk jsBerserk js
Berserk js
 
Django development
Django developmentDjango development
Django development
 
Software Engineer Talk
Software Engineer TalkSoftware Engineer Talk
Software Engineer Talk
 
千呼萬喚始出來的 Java SE 7
千呼萬喚始出來的 Java SE 7千呼萬喚始出來的 Java SE 7
千呼萬喚始出來的 Java SE 7
 
基于 FRIDA 的全平台逆向分析
基于 FRIDA 的全平台逆向分析基于 FRIDA 的全平台逆向分析
基于 FRIDA 的全平台逆向分析
 
Introduction to CodeIgniter
Introduction to CodeIgniterIntroduction to CodeIgniter
Introduction to CodeIgniter
 
Django step0
Django step0Django step0
Django step0
 
2023-netconf-deploy-azure-function-with-KEDA-on-aks
2023-netconf-deploy-azure-function-with-KEDA-on-aks2023-netconf-deploy-azure-function-with-KEDA-on-aks
2023-netconf-deploy-azure-function-with-KEDA-on-aks
 
钱宝坤:多浏览器集成的JavaScript单元测试工具
钱宝坤:多浏览器集成的JavaScript单元测试工具钱宝坤:多浏览器集成的JavaScript单元测试工具
钱宝坤:多浏览器集成的JavaScript单元测试工具
 
Java Build Tool course in 2011
Java Build Tool course in 2011Java Build Tool course in 2011
Java Build Tool course in 2011
 

The Journey of Source Generator

  • 2. The Journey of Source Generator Roberson Liou 2
  • 3. 關於我 • 手沖咖啡科技宅 • Backend Engineer • Microsoft MVP(2020-2021) • twMVC 核心成員 • DevOps Taiwan 志工 • 工程良田的小球場 p.3
  • 4. Outline • Introduce Source Generator • How to use Source Generator? • Demo 4
  • 6. What’s the Source Generator? • .NET 5 釋出的一個 Roslyn 新項目 • 在編譯階段產生程式碼 • 附加至最後的編譯結果 • Compile-time Meta Programing • Meta 來源:SyntaxTree、File、Config p.6
  • 7. What CAN it do? • 取得 Roslyn 編譯後的 Compilation • 取得外部專案的附加檔案 • 取得 Config 的自定義資訊 • 輸出實體檔案到指定資料夾中 • 與 IDE整合輸出診斷資訊 p.7
  • 8. What can NOT it do? • 不能修改原本的程式碼 • 無法達到 AOP 效果 • 可以有多個 Generator,但彼此間不能相互參考 • 不能產生 C# 程式碼以外的檔案 p.8Source Generators: Allow embedding of files other than source #49935
  • 9. Lifecycle - C# Compilation C# code Program.cs Compile IL Code .dll .exe p.9
  • 10. Lifecycle - Invoke Source Generator C# code Program.cs Compile IL Code .dll .exe Invoke Source Generator p.10
  • 11. le Lifecycle - Source Generator IL Invoke Source Generator p.11 Source Generator step of compilation Add generated code to compilation Analyze source code Generate new source code Invoke Source Generator Source Generator
  • 12. Compile Lifecycle - Overall IL Code .dll .exe Invoke Source Generator p.12 Source Generator step of compilation Add generated code to compilation Analyze source code Generate new source code Invoke Source Generator Source Generator C# code Program.cs
  • 13. Benefits • 將 Runtime reflection 轉為 Compile-time • 提升效能 • 處理序列化檔案 • .csv / .xml • 擴增原始程式碼 • partial class / partial method p.13
  • 14. How to use Source Generator?
  • 15. 執行環境 • .NET 5 (SDK 5.0.100) • Visual Studio 2019 (16.8.0+) • JetBrains Rider 2020.3 / EAP 10 p.15
  • 16. Visual Studio 2019 • 需手動叫用 Debugger 偵錯 • 可查看產生的程式碼定義 • 會自動標註 auto-generated • 重新建置後會有快取問題,要重開 VS 才能解決 p.16
  • 17. JetBrains Rider EAP 10 / 2020.3 • 需透過 VS 2019 才能偵錯 • 可查看產生的程式碼定義 • 不會自動標註 auto-generated • 重新建置後即可查看新的建置程式碼 p.17
  • 18. Generator 起手式 • 建立 .NET Standard 2.0 函式庫 • 安裝套件 • Microsoft.CodeAnalysis.CSharp (v3.8.0) • Microsoft.CodeAnalysis.Analyzers (v3.3.1) <ItemGroup> <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.8.0" /> <PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.1" /> </ItemGroup> p.18
  • 19. 在專案中啟用 Generator • 加入專案參考,需額外加入以下兩個屬性。 • OutputItemType="Analyzer" • ReferenceOutputAssembly="false" • 使用 NuGet 套件安裝 Generator 則無須另外設定。 <ItemGroup> <ProjectReference Include="..MyGeneratorLibMyGeneratorLib.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" /> </ItemGroup> p.19
  • 20. Generator 核心成員 • ISourceGenerator • GeneratorAttribute • GeneratorInitializationContext • GeneratorExecutionContext • ISyntaxReceiver p.20 必要實作 初始 執行 篩選 Syntax
  • 21. 實作 Generator • 於類別掛上 [Generator] • 實作 ISourceGenerator • Initialize • Execute [Generator] public class MyGenerator : ISourceGenerator { public void Initialize(GeneratorInitializationContext context){} public void Execute(GeneratorExecutionContext context){} } p.21
  • 22. Generator - Initialize • 主要成員為 GeneratorInitializationContext • context 中具有一個 CancellationToken • RegisterForSyntaxNotifications 可用來註冊 ISyntaxReceiver public void Initialize (GeneratorInitializationContext context) { context.RegisterForSyntaxNotifications( () => new MySyntaxReceiver()); } p.22
  • 23. Example - MySyntaxReceiver public class MySyntaxReceiver : ISyntaxReceiver { public ClassDeclarationSyntax MyClassSyntax { get; private set; } public void OnVisitSyntaxNode(SyntaxNode syntaxNode) { if (syntaxNode is ClassDeclarationSyntax classSyntax) { if (classSyntax.Identifier.ValueText == "MyClass") { MyClassSyntax = classSyntax; } } } } p.23[ Source Generator ] 使用 SyntaxReceiver 快速篩選關注的 Syntax 資訊
  • 24. Generator - Execute • 主要成員為 GeneratorExecutionContext • context 中具有一個 CancellationToken • 從 context 取出各種 meta • 依邏輯產生程式碼字串,並加到最後的編譯結果 • 向 IDE 回報診斷資訊 p.24
  • 25. Generator - AddSource • 將要產生的程式碼加到最後的編譯結果 public void Execute(GeneratorExecutionContext context) { var codeText = @"namespace Sample { public class HelloWorld { public void Say() => Console.WriteLine(""Hello World""); }}}"; context.AddSource("HelloWorld", SourceText.From(codeText, Encoding. UTF8)); } p.25
  • 26. Generator - CancellationToken • 在 Initial 及 Execute 中都有提供 • Generator 會在 IDE 的背景執行 • IDE 提供即時的 Intellisence • 在檔案內容變更時 Generator 會被呼叫 • 提供 IDE 一個取消 Generator 執行的機制 • 可降低 CPU 使用率 p.26[ref] When will generator be canceled?
  • 27. Example - CancellationToken p.27[ref] When will generator be canceled? [Generator] public class MyGenerator : ISourceGenerator { public void Initialize(GeneratorInitializationContext context) { if (!context.CancellationToken.IsCancellationRequested) { } } public void Execute(GeneratorExecutionContext context) { if (!context.CancellationToken.IsCancellationRequested) { } } }
  • 28. 如何偵錯 Generator • 目前無法與 IDE 自動整合 • 必須透過程式手動叫用偵錯器 • 必須手動選擇偵錯執行的 IDE 視窗 public void Initialize (GeneratorInitializationContext context) { System.Diagnostics.Debugger.Launch(); } p.28
  • 29. Getting Advanced – How to retrieve Metadata?
  • 30. Meta 可以從哪裡來? • Compilation • SyntaxTree, SemanticModel • SyntaxRecevier • AddtionalFiles • AnalyzerConfigOptions p.30
  • 31. 取得 Syntax 資訊 • 從 context.Compilation 拿到首次編譯的結果 • 主要對象是 Roslyn 的 Syntax API • 取得 BotAttribute 的 AttributeSyntax var syntaxNodes = compilation .SyntaxTrees.SelectMany(s => s.GetRoot().DescendantNodes()); var attributeSyntaxs = syntaxNodes .Where((d) => d.IsKind(SyntaxKind.Attribute)).OfType<AttributeSyntax>(); var botAttributeSyntax = attributeSyntaxs. FirstOrDefault(x => x.Name.ToString() == "Bot"); p.31
  • 32. 取得 SyntaxReceiver 資訊 • 從 context 取得 SyntaxRecevier 後再做轉型 public void Execute(GeneratorExecutionContext context) { MyClassSyntaxReceiver receiver = (MyClassSyntaxReceiver) context.SyntaxReceiver; var myClassSyntax = receiver.MyClassSyntax; } Additional file transformationp.32
  • 33. 存取附加檔案資訊 • 必須手動於 .csproj 裡面宣告 • 可於 xml 標籤內自訂屬性資訊 • 須明確標記為 CompilerVisibleItemMetadata <ItemGroup> <AdditionalFiles Include="Cars.csv" CacheObjects="true" /> <CompilerVisibleItemMetadata Include="AdditionalFiles" MetadataName="CacheObjects" /> </ItemGroup> Additional file transformationp.33
  • 34. 回報診斷訊息 • 使用 ReportDiagnostic 向 IDE 回報診斷訊息 Context.ReportDiagnostic(Diagnostic.Create( new DiagnosticDescriptor("MYERR001", "TestDiagnostic", $"Here is a error.", "source generator", DiagnosticSeverity.Error, true), Location.None)); [ref] Issue Diagnostics p.34
  • 36. 如何打包成 NuGet package • 設定 GeneratePackageOnBuild 為 true • 設定 IncludeBuildOutput 為 false • 設定 Generator 用的套件標示為 PrivateAssets="all" • 設定 Generator 打包路徑於 analyzer 目錄下 [ref] Package a generator as a NuGet package p.36
  • 37. 如何打包成 NuGet package <PropertyGroup> <GeneratePackageOnBuild>true</GeneratePackageOnBuild> <IncludeBuildOutput>false</IncludeBuildOutput> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.8.0" PrivateAssets="all" /> <PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.1" PrivateAssets="all" /> <!-- 將 Generator 打包路徑指定在 analyzer 目錄下 --> <None Include="$(OutputPath)$(AssemblyName).dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" /> </ItemGroup> [ref] Package a generator as a NuGet package p.37
  • 38. 參考外部的 NuGet 套件 • 當套件用途為供 Generator 執行過程用時 • 必須設定 PrivateAssets 及 GeneratePathProperty 屬性 • 必須額外將 dll 打包到指定的 analyzer 目錄底下 • 套件名稱要改為 Pkg{PACKAGE_NAME} • 遇到點(.)要改為底線 ( _ ) • EX: Newtonfost.Json => PkgNewtonsoft_Json [ref] Use functionality from NuGet packages p.38
  • 39. Example – Pack Newtonsoft.Json <ItemGroup> <PackageReference Include="Newtonsoft.Json" Version="12.0.1" PrivateAssets="all" GeneratePathProperty="true" /> <!-- 將套件 .dll 打包路徑指定在 analyzer 目錄下 --> <None Include="$(PkgNewtonsoft_Json)libnetstandard2.0*.dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" /> </ItemGroup> [ref] Use functionality from NuGet packages p.39
  • 40. 使用案例介紹 • Hello World • DotNetBot • DataBuilder • CSVToList • Mapper p.40 https://github.com/robersonliou/SourceGeneratorJourney
  • 41. 結語 • 尚未與 IDE 偵錯完全整合 • 繞來繞去最後還是得搞 Roslyn • 寫起來很煩,用起來很爽 • 若要收納為團隊用途,請寫說明文件 • 期待 .NET 6 會推出更兇猛的功能 p.41
  • 42. 補充 – Syntax 分析工具介紹 • SyntaxViewer (Visual Studio 2019 內建) • SharpLab • LinqPad p.42
  • 43. 補充 – 使用案例 • DataBuilder • StrongInject • InlineMapper • 官方 Roslyn-SDK 範例 p.43
  • 44. References (Microsoft) • Introducing C# Source Generators • New C# Source Generator Samples • Source Generators Cookbook • Source Generators p.44
  • 45. References (Other) • Generating Code in C# • Source Generators in .NET 5 with ReSharper • Auto generate builders using Source Generator in .NET 5 • Thinking beyond Roslyn source generators and aspect-oriented programming (postsharp) p.45
  • 46.  .NET 5.0 released today!  Major releases every year in November  LTS for even numbered releases  Predictable schedule, minor releases as needed .NET Schedule Nov 2020 .NET 5.0 Nov 2021 .NET 6.0 LTS Nov 2022 .NET 7.0 Nov 2023 .NET 8.0 LTS Nov 2024 .NET 9.0