攔截器Interceptors是一種可以在編譯時以宣告方式替換原有應用的方法。
這種替換是透過讓Interceptors宣告它攔截的呼叫的源位置來實現的。
您可以使用攔截器作為源生成器的一部分進行修改,而不是向現有源編譯新增程式碼。
演示
使用 .NET 8 建立一個控制檯應用程式。並在PropertyGroup中新增以下配置.。需要將其中WebApplication6替換為自己的名稱空間。
<InterceptorsPreviewNamespaces>$(InterceptorsPreviewNamespaces);WebApplication6</InterceptorsPreviewNamespaces>
然後在單獨的檔案中建立InterceptsLocationAttribute。其名稱空間必須是System.Runtime.CompilerServices,而不是應用程式的名稱空間。
namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] public sealed class InterceptsLocationAttribute(string filePath, int line, int character) : Attribute { } }
該屬性包含三個引數。
- filePath是您要攔截的檔案的路徑。
- line是您要攔截的程式碼行。
- character是您要攔截的程式碼字元位置。
接著來建立一個具有三種方法的類,模擬新增/查詢使用者作為示例:
public class GetUserService { // This method will not be intercepted; public void GetUserName() { Console.WriteLine("GetUserName"); } // This method will be intercepted; public void AddUser() { Console.WriteLine("AddUser"); } // This method will not be intercepted; public void DeleteUser() { Console.WriteLine("DeleteUser"); } }
在 Program.cs 檔案中,我建立了此類的一個例項,並建立了對這三個方法中每一個的呼叫。輸出如下所示:
var userService = new GetUserService(); userService.GetUserName(); userService.AddUser(); userService.DeleteUser();
現在讓我們建立攔截類。該類必須遵循以下規則:
- 一定是一個static類。
- 必須是我們要攔截的類的擴充套件方法。
- 必須具有該InterceptsLocation屬性,其中包含我們要攔截的檔案路徑的值以及行號和字元號。
using System.Runtime.CompilerServices; namespace WebApplication6 { public static class InterceptUserService { [InterceptsLocation( filePath: @"D:\demo\test\ConsoleApp1\WebApplication6\Program.cs", line: 14, character: 25)] public static void InterceptMethodAddUser(this GetUserService example) { Console.WriteLine("Interceptor is here!"); } } }
在此示例中,將攔截AddUser方法,並且將執行InterceptMethodAddUser方法,而不是執行方法AddUser。
filePath可以按以下方式獲取
行號和字元號可以按以下方式獲取
現在執行程式碼,方法AddUser將被攔截,並且不會被執行,而是實際執行攔截器方法,以下是輸出: