一直有很多轉(zhuǎn)載dotnet對(duì)Interceptor說明文檔的,但鮮有說明Interceptor如何使用的,這里寫一篇簡(jiǎn)單示例來展示一下 c# 12 實(shí)驗(yàn)特性Interceptor 是什么? 官方解釋如下(其實(shí)簡(jiǎn)單說就是語言特性中內(nèi)置的靜態(tài)編織方式的aop功能,不同于其他il修改代碼的方式,使用上得結(jié)
在dotnet社區(qū)中,雖然有很多關(guān)于Interceptor的轉(zhuǎn)載說明文檔,但很少有關(guān)于Interceptor如何使用的詳細(xì)說明。本文將通過一個(gè)簡(jiǎn)單示例來展示Interceptor的使用方法。
Interceptor是一種內(nèi)置的靜態(tài)編織方式的aop功能,與其他il修改代碼的方式不同。它可以在編譯時(shí)以聲明方式將對(duì)可攔截方法的調(diào)用替換為對(duì)其自身的調(diào)用。通過讓攔截器聲明所攔截調(diào)用的源位置,可以進(jìn)行這種替換。攔截器可以向編譯中(例如在源生成器中)添加新代碼,從而提供更改現(xiàn)有代碼語義的有限能力。
在源生成器中使用攔截器修改現(xiàn)有編譯的代碼,而非向其中添加代碼。源生成器將對(duì)可攔截方法的調(diào)用替換為對(duì)攔截器方法的調(diào)用。
如果你有興趣嘗試攔截器,可以閱讀功能規(guī)范來了解詳細(xì)信息。如果使用該功能,請(qǐng)確保隨時(shí)了解此實(shí)驗(yàn)功能的功能規(guī)范中的任何更改。最終確定功能后將在微軟文檔站點(diǎn)上添加更多指導(dǎo)。
這里我們用一個(gè)簡(jiǎn)單的 static method 作為我們改寫方法內(nèi)容的目標(biāo)。
public static partial class DBExtensions
{
public static string TestInterceptor(object o)
{
return o.GetType().ToString();
}
}
這樣的靜態(tài)方法,我們假設(shè)改寫的目標(biāo)為返回o參數(shù)的其中一個(gè)string類型的屬性值。
所以應(yīng)該可以通過如下的 UT 方法:
[Fact]
public void CallNoError()
{
Assert.Equal("sss", DBExtensions.TestInterceptor(new { A = "sss", C= "ddd" }));
}
建立一個(gè) netstandard2.0 的類庫(kù)并設(shè)置如下:
netstandard2.0
preview
true
false
Generated 目錄生成代碼文件其實(shí)是非必須的,但是為了方便大家看到 source generater 生成的代碼文件內(nèi)容,對(duì)于我們初次嘗試source generater很有幫助。
net8.0
enable
enable
false
true
Generated
$(InterceptorsPreviewNamespaces);Test.AOT
[Generator(LanguageNames.CSharp)]
public class InterceptorGenerator : IIncrementalGenerator
{
}
這里的
IIncrementalGenerator
為source generater更強(qiáng)設(shè)計(jì)的一代接口,有更強(qiáng)的性能和更方便的能力。接著我們來實(shí)現(xiàn)接口。
[Generator(LanguageNames.CSharp)]
public class InterceptorGenerator : IIncrementalGenerator
{
public void Initialize(IncrementalGeneratorInitializationContext context)
{
var nodes = context.SyntaxProvider.CreateSyntaxProvider(FilterFunc, TransformFunc).Where(x => x is not null).Select((x, _) => x!);
var combined = context.CompilationProvider.Combine(nodes.Collect());
context.RegisterImplementationSourceOutput(combined, Generate);
}
}
接著我們來實(shí)現(xiàn)
FilterFunc
。
private bool FilterFunc(SyntaxNode node, CancellationToken token)
{
if (node is InvocationExpressionSyntax ie && ie.ChildNodes().FirstOrDefault() is MemberAccessExpressionSyntax ma)
{
return ma.Name.ToString().StartsWith("TestInterceptor");
}
return false;
}
接著我們來實(shí)現(xiàn)
TransformFunc
。
private TestData TransformFunc(GeneratorSyntaxContext ctx, CancellationToken token)
{
// 實(shí)現(xiàn)代碼
}
接著我們來實(shí)現(xiàn)
Generate
。
private void Generate(SourceProductionContext ctx, (Compilation Left, ImmutableArray Right) state)
{
// 實(shí)現(xiàn)代碼
}
如果我們編譯程序,就會(huì)看見生成了這樣的文件代碼。
// 生成的代碼
如果運(yùn)行ut,結(jié)果也正確,debug逐行調(diào)試也可看到斷點(diǎn)能進(jìn)入我們生成的代碼文件中。
小編推薦閱讀機(jī)器學(xué)習(xí):神經(jīng)網(wǎng)絡(luò)構(gòu)建(下)
閱讀華為Mate品牌盛典:HarmonyOS NEXT加持下游戲性能得到充分釋放
閱讀實(shí)現(xiàn)對(duì)象集合與DataTable的相互轉(zhuǎn)換
閱讀鴻蒙NEXT元服務(wù):論如何免費(fèi)快速上架作品
閱讀算法與數(shù)據(jù)結(jié)構(gòu) 1 - 模擬
閱讀5. Spring Cloud OpenFeign 聲明式 WebService 客戶端的超詳細(xì)使用
閱讀Java代理模式:靜態(tài)代理和動(dòng)態(tài)代理的對(duì)比分析
閱讀Win11筆記本“自動(dòng)管理應(yīng)用的顏色”顯示規(guī)則
閱讀本站所有軟件,都由網(wǎng)友上傳,如有侵犯你的版權(quán),請(qǐng)發(fā)郵件[email protected]
湘ICP備2022002427號(hào)-10 湘公網(wǎng)安備:43070202000427號(hào)© 2013~2025 haote.com 好特網(wǎng)