1. 程式人生 > >基於 Source Generators 做個 AOP 靜態編織小實驗

基於 Source Generators 做個 AOP 靜態編織小實驗

# 0. 前言 上接:用 Roslyn 做個 JIT 的 AOP 作為第二篇,我們基於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 * gRPC * Resx file generation * System.CommandLine * Serializers * SWIG  ## 1.2 目前其設計和使用準則 允許開發者能在編譯時動態建立新增新程式碼到我們程式裡面 只能新增程式碼,不能修改已有程式碼 當無法生成源時,生成器應當產生診斷資訊,通知使用者問題所在。 可能訪問其他檔案非c#原始碼檔案。 無序執行模式,每個生成器都只能擁有相同的輸入編譯,即不能用其他生成器的生成結果進行再次生成。 生成器的執行類似於分析器。  # 2. 實驗:代理模式的靜態編織 ## 2.1 建立一個Source Generators專案 ``` ``` ## 2.2 建立SourceGenerator 需要繼承 `Microsoft.CodeAnalysis.ISourceGenerator` ``` namespace Microsoft.CodeAnalysis { public interface ISourceGenerator { void Initialize(InitializationContext context); void Execute(SourceGeneratorContext context); } } ``` 並通過[Generator]標識啟用  所以我們就可以做一個這樣的代理生成器: ``` using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Text; using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace AopAnalyzer { [Generator] public class ProxyGenerator : ISourceGenerator { public void Execute(SourceGeneratorContext context) { // retreive the populated receiver if (!(context.SyntaxReceiver is SyntaxReceiver receiver)) return; try { // 簡單測試aop 生成 Action