Native AOT 환경에서 **리플렉션(Reflection)**은 정적 분석을 방해하고 트리밍 과정에서 필요한 코드를 삭제하게 만들므로 기본적으로 호환되지 않습니다. 이를 대체하여 애플리케이션의 성능과 안정성을 보장하기 위해 권장되는 기술은 다음과 같습니다.
1. 소스 생성기 (Source Generators) - 가장 권장되는 기술
소스 생성기는 리플렉션이 수행하던 '런타임 탐색'을 '컴파일 시점'으로 이동시키는 기술로, AOT 시대의 표준 해결책으로 간주됩니다.
- 작동 방식: 컴파일 중에 코드를 스캔하여 필요한 로직(예: 직렬화 코드, 의존성 주입 매핑)을 미리 생성합니다.
- 이점: 런타임 오버헤드가 전혀 없으며, 100% AOT 호환성을 유지하면서도 시작 속도를 최대 40% 이상 단축할 수 있습니다.
- 적용 사례: System.Text.Json의 직렬화, ASP.NET Core의 로깅 및 Minimal API 지원, .NET 8 이상의 의존성 주입(DI) 등이 이 기술을 사용합니다.
2. 정적 참조 및 수동 등록
문자열 기반의 동적 탐색 대신 컴파일러가 추적할 수 있는 방식을 사용합니다.
- 정적 참조 (Static References): Type.GetType("MyLib.Foo")와 같은 위험한 문자열 기반 호출 대신 typeof(Foo)를 사용하여 컴파일러가 해당 타입의 사용처를 명확히 알 수 있게 합니다.
- 수동 타입 등록 (Manual Registration): 어셈블리를 전체 스캔하는 방식 대신, 필요한 타입을 딕셔너리 등에 수동으로 등록하여 관리합니다.
3. 트리머 힌트 및 특성 (Attributes)
기존 코드를 크게 수정하기 어려울 때 트리머에게 특정 코드를 보존하라고 알려주는 보조 기술입니다.
- DynamicallyAccessedMembers 특성: 리플렉션을 통해 접근할 멤버(예: 생성자, 메서드)를 명시하여 트리머가 이를 삭제하지 않도록 보호합니다.
- ILLink XML 설명자 (Descriptors): XML 파일을 통해 특정 어셈블리나 타입을 강제로 보존하도록 설정합니다. 이는 플러그인 아키텍처나 기존 라이브러리 마이그레이션 시 유용합니다.
4. Reflection.Emit 대체 기술
Native AOT는 실행 중 IL 코드를 생성하는 Reflection.Emit을 지원하지 않습니다.
- 대안: **식 트리 인터프리터(Expression tree interpreters)**를 사용하거나(단, 성능은 느림), 가능한 경우 모든 동적 로직을 소스 생성기로 전환해야 합니다.
요약하자면: 가장 강력하고 미래 지향적인 대안은 소스 생성기를 사용하는 것입니다. 이는 런타임에 "누가 있는지" 찾아다니는 대신, 빌드 시점에 "누가 필요한지" 명단을 확정하고 그에 맞는 코드를 미리 작성해 두는 방식입니다.
이 차이를 비유하자면, 리플렉션은 손님이 도착한 후에야 냉장고를 뒤져 재료를 찾고 요리법을 고민하는 식당과 같고, 소스 생성기(AOT 호환 기술)는 예약된 손님의 수에 맞춰 모든 재료를 미리 손질하고 요리 준비를 마쳐둔 식당과 같습니다. 후자는 준비 과정(빌드 시간)이 더 필요하지만, 손님이 오자마자(실행 시) 즉시 최고의 요리를 내놓을 수 있습니다.
'[프로그래밍]' 카테고리의 다른 글
| 한 애플리케이션 내에 단 하나의 닷넷 정적 라이브러리만 링킹할 수 있는 이유 (1) | 2025.12.26 |
|---|---|
| PGO(Profile-Guided Optimization, 프로필 기반 최적화) (0) | 2025.12.26 |
| Native AOT 프로젝트 파일에 추가해야 할 필수 속성은? (0) | 2025.12.26 |
| Native AOT가 JIT보다 시작 속도가 빠른 이유는? (2) | 2025.12.26 |
| Native AOT 빌드 시 사용 가능한 두 가지 최적화 모드는? (0) | 2025.12.26 |





