C# 12 Interceptors — 컴파일 타임 메서드 교체
Interceptors는 C# 12에서 도입된 실험적 기능으로, 특정 호출 사이트(call site)의 메서드 호출을 컴파일 타임에 다른 메서드로 교체합니다. Source Generator와 함께 사용해 AOT 최적화, 성능 개선, 코드 분석 도구 등에 활용됩니다.
주의: .NET 8 기준 실험적 기능(
[Experimental])입니다. 향후 API가 변경될 수 있습니다.
1. 프로젝트 설정
섹션 제목: “1. 프로젝트 설정”<PropertyGroup> <InterceptorsPreviewNamespaces>MyApp.Generated</InterceptorsPreviewNamespaces></PropertyGroup>2. 기본 구조
섹션 제목: “2. 기본 구조”// 원본 코드namespace MyApp;
public class Greeter{ public string Hello(string name) => $"Hello, {name}!";}
// 호출 사이트 (Program.cs, 5번째 줄 14번째 열)var g = new Greeter();var msg = g.Hello("World"); // ← 이 호출을 교체// Generated/Interceptors.cs (Source Generator 출력)using System.Runtime.CompilerServices;
namespace MyApp.Generated;
file static class GreeterInterceptors{ [InterceptsLocation("Program.cs", line: 5, character: 14)] public static string Hello_Intercepted(this Greeter g, string name) => $"안녕하세요, {name}!"; // 교체된 구현}3. Source Generator와 연계
섹션 제목: “3. Source Generator와 연계”[Generator]public class InterceptorGenerator : IIncrementalGenerator{ public void Initialize(IncrementalGeneratorInitializationContext context) { var calls = context.SyntaxProvider .CreateSyntaxProvider( predicate: (node, _) => node is InvocationExpressionSyntax, transform: (ctx, _) => GetCallInfo(ctx)) .Where(info => info is not null);
context.RegisterSourceOutput(calls, (ctx, info) => { var source = GenerateInterceptor(info!); ctx.AddSource($"Interceptor_{info!.Location}.g.cs", source); }); }}4. 실전 활용 사례
섹션 제목: “4. 실전 활용 사례”4.1 AOT 호환 JSON 직렬화
섹션 제목: “4.1 AOT 호환 JSON 직렬화”ASP.NET Core의 Minimal API는 Interceptors를 이용해 JsonSerializer.Deserialize<T>() 호출을 AOT 친화적인 Source Generated 버전으로 자동 교체합니다.
// 원본 호출app.MapPost("/user", (User u) => Results.Ok(u));
// 컴파일 후 — Interceptor가 AOT 직렬화 코드로 교체// JsonSerializer.Deserialize<User>(...)// → UserJsonContext.Default.User 사용4.2 로깅 최적화
섹션 제목: “4.2 로깅 최적화”// 원본logger.LogInformation("User {Id} logged in", userId);
// Interceptor → 컴파일 타임 LoggerMessage 생성으로 교체// → 런타임 문자열 보간 제거5. InterceptsLocation 속성
섹션 제목: “5. InterceptsLocation 속성”[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]public sealed class InterceptsLocationAttribute : Attribute{ public InterceptsLocationAttribute(string filePath, int line, int character) { }}filePath: 소스 파일 경로 (프로젝트 기준 상대 경로)line: 호출 사이트의 줄 번호 (1 기반)character: 호출 사이트의 열 번호 (1 기반)
6. 제약 사항
섹션 제목: “6. 제약 사항”| 항목 | 내용 |
|---|---|
| 상태 | 실험적 기능 (Experimental) |
| 적용 범위 | 인스턴스 메서드, 정적 메서드, 확장 메서드 |
| 불가 대상 | 생성자, 연산자, 속성 접근자 |
| 도구 | Source Generator 없이 수동 작성도 가능 (비권장) |
Interceptors는 직접 사용보다는 프레임워크와 라이브러리가 내부적으로 활용하는 메커니즘입니다. ASP.NET Core, EF Core 등이 AOT 최적화를 위해 적극 채택 중이며, 동작 원리를 이해하면 생성된 코드를 읽고 디버깅하는 데 큰 도움이 됩니다.