前面我們使用了IIncrementalGenerator來生成程式碼,接下來我們來詳細瞭解下IIncrementalGenerator的核心部分IncrementalValueProvider。
介紹
IncrementalValueProvider是基於管道的模式,將我們需要的資料進行處理轉換後傳遞給SourceOutput。
目前官方提供可用的Providers有如下幾種:
- CompilationProvider
- AdditionalTextsProvider
- AnalyzerConfigOptionsProvider
- MetadataReferencesProvider
- ParseOptionsProvider
實操
接下來我們來使用AdditionalTextsProvider來學習IncrementalValueProvider的執行方式。
建立專案
首先建立LearnIncrementalValueProvider的控制檯程式和LearnIncrementalValueProvider.Analysis的netstandard2.0類庫兩個專案。
按照前面HelloWorld專案的專案配置進行配置和引用。
新增LearnIncrementalValueProviderGenerator
在LearnIncrementalValueProvider.Analysis中新增LearnIncrementalValueProviderGenerator繼承並實現IIncrementalGenerator介面。
using Microsoft.CodeAnalysis;
using System;
using System.Diagnostics;
namespace LearnIncrementalValueProvider.Analysis
{
[Generator]
public class LearnIncrementalValueProviderGenerator : IIncrementalGenerator
{
public void Initialize(IncrementalGeneratorInitializationContext context)
{
Debugger.Launch();
var additionalTextsProvider = context.AdditionalTextsProvider;
context.RegisterSourceOutput(additionalTextsProvider, (ctx, additionalTexts) =>
{
var path = additionalTexts.Path;
var text = additionalTexts.GetText(ctx.CancellationToken);
});
}
}
}
在實現的程式碼中,獲取到AdditionalTextsProvider,並直接傳遞給RegisterSourceOutput,並在委託方法中直接獲取AdditionalTextsProvider的檔案路徑以及文字內容。
在方法中加入Debugger.Launch();方便除錯。
新增檔案和除錯
在控制檯程式中,新增一個Files目錄。往裡面塞入一個swagger.json檔案。
此時直接除錯會發現,斷點並不會進入到RegisterSourceOutput的委託中。
這是因為AdditionalTextsProvider並沒有找到任何需要載入的檔案。
我們需要在控制檯程式的專案檔案中新增AdditionalFiles,指定需要監聽的檔案。
<ItemGroup>
<AdditionalFiles Include="Files/*" />
</ItemGroup>
新增AdditionalFiles後,在除錯一次。
可以看到斷點成功進來了。並且可以看到獲取的檔案路徑以及檔案的文字內容。
多個檔案
在Files目錄中新增一個txt檔案。並寫入文字HelloWorld
然後再除錯一次。可以發現,每一個檔案都會單獨執行一次委託的方法。
過濾檔案
當我們只需要其中一種型別的檔案的時候,我們可以透過Where來進行過濾篩選。
透過Debugger.Log可以發現,只輸出了json的檔案路徑。
處理資料
可以使用Select來處理我們的資料,比如這裡我只獲取檔名稱。透過Debugger.Log可以看到輸出了兩個檔名稱。
集合
如果不想多次處理檔案的話,可以使用Collect方法,直接把多個檔案合併在一起。
這裡可以看到,使用Collect,2個檔案可以同時處理。
組合多個IncrementalValueProvider
除了對單個IncrementalValueProvider進行處理外,我們還可以組合不同的IncrementalValueProvider。
比如將CompilationProvider和AdditionalTextsProvider組合起來。
使用Combine方法。
可以看到 paris的Right和Left分別是CompilationProvider和AdditionalTextsProvider兩種型別。
結語
以上就是IncrementalValueProvider比較常用的方式。透過這些操作可以靈活的實現我們的程式碼生成邏輯。
當然還有其他的IncrementalValueProvider,這裡就不都寫出來了。其他的可以自己實操玩起來~
本文程式碼倉庫地址https://github.com/fanslead/Learn-SourceGenerator