한 주 동안 .NET 생태계에서 있었던 주요 이슈와 아티클, 기술 트렌드를 정리해 소개합니다.
.NET 11 RC1 공개 — go-live 라이선스와 C# 15 확정
- 저자: .NET 팀
- 태그: #dotnet11 #csharp15 #releasenotes
주요 내용
- go-live 지원 라이선스가 부여되어 프로덕션 사용이 가능하며 Visual Studio 2026 Insiders와 VS Code C# Dev Kit에서 지원
- C# 15가 .NET 11 기본 언어 버전으로 확정되고 union 타입, closed class hierarchy, non-virtual static interface member, labeled break/continue, extension indexer가 정식화
- 런타임은 Unix 인프로세스 크래시 리포터 확장과 s390x 지원을 추가했고, JIT가 x64 AVX10.1/F16C·Arm64 FP16 명령어로
System.Half연산을 가속 - 라이브러리는
Process종료 시그널·상태 조회 API, 실험적 caller-driven TLS 세션, Linux DNS 레코드 조회, JSON의 새 숫자 타입과 union 직렬화를 추가 - ASP.NET Core는 SignalR 인증 리프레시 API와 Blazor Server 회로 갱신을 추가했고,
decimal/BigInteger↔부동소수점 변환 반올림 방식 변경에는 호환 스위치가 없음
.NET·.NET Framework 9월 서비싱 업데이트 — CVE 8건
- 저자: Rahul Bhandari, Tara Overfield
- 태그: dotnet #servicing #cve
주요 내용
- .NET 10.0.12, 9.0.20, 8.0.31과 .NET Framework 4.6.2·4.7·4.7.1·4.7.2·4.8·4.8.1을 함께 다루는 통합 서비싱 릴리스
- CVE-2026-69805, CVE-2026-69439, CVE-2026-71328, CVE-2026-69304, CVE-2026-58649, CVE-2026-66822, CVE-2026-69806이 .NET 10.0/9.0/8.0에 영향
- CVE-2026-69522는 .NET과 .NET Framework 양쪽 모두에 영향을 미치는 공통 취약점
- 개별 버그 수정 목록은 본문에 나열하지 않고 GitHub 릴리스 노트와 MSRC 링크로 안내
ASP.NET Core에서 C# 유니온과 닫힌 계층 사용하기
- 저자: Dmitrii Korolev
- 태그: #csharp15 aspnetcore #unions
주요 내용
- discriminator 필드 없이 여러 타입 중 하나를 표현해야 하는 상황을 Kubernetes
maxUnavailable(정수 또는 퍼센트 문자열) 사례로 제시 public union IntOrString(int, string);문법으로 union을 선언하면 캐스팅 없는 대입이 가능하고switch패턴 매칭에서 컴파일러가 완전성을 검사closed한정자가 외부 어셈블리의 상속을 차단해 컴파일러가 파생 타입 집합을 고정된 것으로 처리하며,[JsonPolymorphic(InferClosedTypePolymorphism = true)]로 타입명 기반$typediscriminator를 자동 추론- Minimal API, MVC, SignalR, Blazor(JS interop·상태 유지), OpenAPI(
anyOf스키마)까지 통합 - union은 쿼리스트링·라우트 값·헤더·폼 필드 바인딩이 불가능하고, discriminator 없는 구조적 분류는 페이로드 크기에 비례한 스캔 오버헤드가 발생
배포하는 것을 테스트하라 — MSTest와 Native AOT
- 저자: Amaury Levé
- 태그: #mstest nativeaot #sourcegenerator
주요 내용
- MSTest 4.4부터 테스트 프로젝트를 Native AOT 실행 파일로 게시·실행 가능
System.Text.Json리플렉션 직렬화가 매니지드 모드에서는 통과하지만 Native AOT에서는 “reflection-based serialization has been disabled” 오류로 실패하는 사례로 문제를 제시- 소스 생성기가 빌드 시점에 테스트 클래스 레지스트리, 속성 메타데이터, 생성자·호출 델리게이트, 트리밍 호환 참조를 생성해 트리밍 이전에 테스트 존재 여부를 기록
MSTest.Sdk/4.4.0과<PublishAot>true</PublishAot>최소 설정,dotnet publish -r linux-x64명령 제시- 상속만으로
[TestClass]인 클래스, 비공개·파일 로컬·정적·제네릭 테스트 클래스,ref/out/in매개변수 제네릭 테스트,[AssemblyFixtureProvider]는 지원 대상에서 제외
Rider와 ReSharper는 왜 느리게 시작했나 — 범인은 Defender
- 저자: Alexander Ulitin, Michael Hawker
- 태그: rider #resharper #windowsdefender
주요 내용
- ReSharper가 out-of-process 아키텍처로 전환된 후 Windows 최초 실행에 10~40초가 걸렸고 Microsoft 자체 도구는 1초 미만이었음
- Microsoft Defender가 새로 실행된 프로세스를 스캔하는 방식이 원인이며, 파일이 쓰기 보호 디렉터리에 있으면 최적화 스캔(약 2초), 사용자 쓰기 가능 디렉터리에 있으면 전체 스캔(약 50초)이 적용됨
- Defender의 ETW
StreamScanRequestTask이벤트와 PowerShell 모듈로 스캔 소요 시간을 측정해 원인을 규명 - Microsoft가 Defender 1.449.454.0에서 해당 시나리오를 최적화해 쓰기 보호 디렉터리 설치 시 스캔 시간을 5초 미만으로 단축
- JetBrains Toolbox 설치 시 Defender 제외 설정을 적용하면 최초 실행 시간이 약 절반으로 감소하며, 유사 문제 분석용 Defender Performance Tool을 GitHub에 공개
EF Core 스펙으로 Include·프로젝션·추적 제어하기
- 저자: Nick Cosentino
- 태그: #efcore #specificationpattern linq
주요 내용
- 스펙이 불리언 조건을 넘어 쿼리 결과의 형태 자체를 규정한다는 관점을 제시하며 include는 조건자가 아니고, 추적은 성능 토글이 아니며, 프로젝션은 결과 계약을 바꾼다고 정리
Customer/Order엔티티로 DTO 프로젝션과 엔티티 그래프 로딩을 대비- 필터링된 include에서 정렬·
Skip·Take를 조합하는 방법과AsTracking()/AsNoTracking()/AsNoTrackingWithIdentityResolution()선택 기준 - 단일 쿼리와 분할 쿼리의 조인 폭발 대 왕복 횟수 트레이드오프
ReaderCommandCounter인터셉터로 SQLite에서 실제 실행되는 SQL 커맨드 수를 세는 xUnit 테스트로 검증
.NET 라이브러리의 공개 API를 생성하고 리뷰하기
- 저자: Gérald Barré
- 태그: dotnet #apidesign #tooling
주요 내용
Meziantou.Framework.PublicApiGenerator로 어셈블리의 공개 API를 C# 문법의 정규화된 스냅샷 파일로 생성- 기존
Microsoft.CodeAnalysis.PublicApiAnalyzers가 C# 문법이 아니고 멀티 타겟팅에 취약한 점을 지적 - CLI 도구, MSBuild 통합(
PublicApiGeneratorOutputPath), 라이브러리 직접 사용 세 가지 방식 제공 - 멀티 타겟팅 시
#if NET10_0/#elif NET8_0전처리기 지시문으로 프레임워크별 차이를 병합 출력 - .NET 11/C# 15의 closed hierarchy와 union type 문법도 반영하며
--verify-no-change플래그로 CI에서 의도치 않은 API 변경을 차단
.NET 9·10의 CoreCLR GC 핸들 변경
- 저자: Austin Wise
- 태그: dotnet10 #gc #interop
주요 내용
- 기존
GCHandle구조체를 대체하는 제네릭 타입GCHandle<T>,WeakGCHandle<T>,PinnedGCHandle<T>와GCHandleExtensions도입 - 타입 검사를 컴파일 타임으로 옮겨
AddrOfPinnedObject()를 비고정 핸들에 호출하는 오류를 컴파일 오류로 전환 - 새 제네릭 핸들은 널 검사·타입 검증 없이 단순 역참조만 수행해 기존 대비 약 26% 빠른 벤치마크 결과
- .NET 9에 추가된 Weak Interior Pointer Handle은 GC 이동 시 비관리 메모리의 보조 포인터를 갱신하며 collectable assembly의 정적 변수 관리에 사용됨
- .NET 10에 추가된 Cross-Reference Handle은 MAUI Android에서 .NET 힙과 Java 힙 간 컬렉션을 강한 연결 요소 분석으로 조율
누가 묻는가 — 아무것도 증명하지 않는 헬스체크
https://medium.com/@psatishkrishna/whos-asking-45f86d86faf5
- 저자: Satish Krishna
- 태그: dotnet10 #healthchecks aspnetcore
주요 내용
- Liveness probe에는 재시작으로 해결 가능한 항목만 포함해야 한다며
WorkerHeartbeat로 백그라운드 워커 생존을 확인하는 예시 제시 - Readiness probe는 실제 사용하는 의존성을 검사해야 하며, 테이블명을 명시하지 않는 쿼리는 테이블이 삭제돼도 통과함
IHostedLifecycleService.StoppingAsync()로 Kestrel이 연결을 끊기 전에 readiness gate를 먼저 닫는 정상 종료 구현- 범용
CanConnectAsync()체크와 도메인 특화 쿼리 체크를 대조 ReadinessGate,WorkerAliveCheck,QuotesApiCheck구현 코드와 종료 시점별 연결 처리 타이밍 측정 결과 제시
도메인 이벤트는 당신의 퍼블릭 API가 아니다
- 저자: Derek Comartin
- 태그: #eventdrivenarchitecture #domainevents #ddd
주요 내용
- 도메인 이벤트를 외부에 그대로 노출하면 DB 스키마를 API로 직접 노출하는 것과 같은 결합이 생긴다고 지적
- 데이터베이스 모델·도메인 모델·통합 이벤트를 서로 다른 세 모델로 구분
- 물류 배차 예시에서 내부 이벤트(TruckReserved, CarrierAssigned, DispatchInstructionsSent, ETACalculated, ShipperNotified)를 퍼블릭 통합 이벤트
OrderDispatched하나로 요약해 발행 TruckOrderNotUsed와TruckOrderCanceledBeforeShipment처럼 비즈니스적으로 다른 상황을 구분해 인보이싱·차량관리·정산에 미치는 영향 차이를 설명- ID만 담아 동기 콜백을 유발하는 방식과 전체 엔티티 스냅샷 방식을 모두 피하고, 이벤트가 잦은 버전 변경을 겪으면 미발견 비즈니스 개념의 신호로 볼 것을 제안
C#으로 만든 오픈소스 텔레그램 서버, 4년 후
- 저자: Aykut Alparslan Koc
- 태그: csharp #mtproto #systemdesign
주요 내용
- 4년 전
SocketAsyncEventArgs/IValueTaskSource/System.IO.Pipelines기반 TCP 에코 서버에서 출발한 프로젝트가 현재 Ferrite로 발전 - .NET 10 대상이며 텔레그램 API 레이어 214의 732개 메서드 중 494개를 디스패치하고, 패치된 공식 안드로이드·iOS 클라이언트로 로그인·메시지·그룹/채널·파일 전송·시크릿 챗·통화까지 검증
- MTProto 메시지를 인증키 처리 → 컨테이너 언팩 → gzip 해제 → 서비스 메시지 소비 → 실행 엔진 전달의 처리 체인으로 구성해 연결 객체 코드 비대화를 방지
- 자체 소스 생성기
Ferrite.TLParser로 TL 스키마에서 C# 리더·라이터를 생성하고, 일반·스트리밍·파일 요청을 별도 계약으로 분리해 공통 경로가 파일 스트림을 짊어지지 않게 설계 - 분산 프로파일에서 Cassandra·Redis·MinIO·Elasticsearch·Kafka를 조합하되 MTProto 연결은 노드에 로컬로 유지한 채 envelope로 상태만 동기화
가벼운 읽을거리
후보 항목 중 이슈로 선정되지 않은 가벼운 읽을거리들
MSIX PackageVolume — 패키지 저장소가 동작하는 방식
- MSIX 패키지가 스테이징되는 설치 저장소를 관리하는 Windows 추상화로, 시스템 드라이브 외에 이동식 미디어·네트워크 공유까지 지원
- 패키지를 드라이브 문자 대신 저장 볼륨의 미디어 ID로 식별해 마운트 지점이 바뀌어도 일관되게 인식되며, 비-시스템 볼륨은 오프라인 접근을 통한 보호 우회를 막기 위해 암호화됨
AddPackageVolumeAsync(),FindPackageVolume(),SetDefaultPackageVolume()등 API와 PowerShell 대응 명령 제공
더 나쁜 것이 더 낫다 — C# 대 F#
- 같은 .NET 위에서 돌아가 빌드 도구·호스팅 변수를 배제하고 언어 자체만 비교할 수 있는 쌍이라는 전제에서 출발
- F#이 기본적으로 순환 의존성을 허용하지 않아 아키텍처 건전성을 컴파일 타임에 강제한다는 점을 핵심 장점으로 제시
- C# 쪽 장점으로 Razor 호환성, IDE 지원, 순환 복잡도·커버리지·뮤테이션 테스트 툴링을 인정
C#으로 PDF에서 표 추출을 시도했다 — 어디서 깨지는가
- 텍스트 조각의 수직 정렬로 행을 묶고 헤더 위치로 열을 배정하는 2단계 기하학적 재구성 기법을 PdfPig으로 구현
- 병합·스팬 셀, 여러 줄 래핑, 테두리 없는 불규칙 표, 페이지당 다중 표에서 재구성이 깨지는 실패 사례를 좌표 수준으로 기술
- 스캔 문서는 OCR이 필요하나 C#에 대응 라이브러리가 없어 PP-OCRv5·ONNX Runtime 등 Python 기반 비전 모델로 넘어가야 한다고 결론
최종적 일관성 이해하기
- 강한 일관성은 노드 간 조정 비용이 크며 쓰기 지연이 가장 느린 노드와 네트워크에 의해 제한됨을 설명
- CAP 정리상 파티션 내성이 필수이므로 실제로는 일관성과 가용성 중 선택만 남는다고 정리하고 MongoDB·HBase(CP), Cassandra·DynamoDB(AP)를 예로 제시
- Cassandra QUORUM/ONE, DynamoDB 강한 일관성 읽기(비용 2배), MongoDB writeConcern 등 연산별 조정 옵션과, 금융 거래·재고 예약·토큰 무효화처럼 즉시 일관성이 필요한 예외를 구분
유니온 타입? 아니, 판별 유니온
- C# 유니온 타입을 JSON으로 역직렬화할 때 “JSON value type ‘Object’ is ambiguous for union type” 오류가 나는 원인은 케이스 타입을 식별할 디스크리미네이터가 없기 때문
[DiscriminatedUnion]속성과IIncrementalGenerator기반 소스 생성기로 생성자·디스크리미네이터 enum·커스텀JsonConverter<T>를 자동 생성- 생성된 컨버터가
$discriminator필드로 케이스를 구분해 역직렬화 모호성을 해소
Ardalis.Specification과 EF Core — 버전 핀과 캐시의 함정
- 패키지 9.3.1이 net10.0을 직접 타겟하지 않고 net8.0/net9.0만 지원한다는 버전 호환성 경고
DbSet.ToListAsync(spec)과WithSpecification().ToListAsync()의 후처리 적용 여부가 다르고,EnableCache/WithCacheKey는 메타데이터일 뿐 실제 캐싱을 수행하지 않음WithSpecification직접 사용, 커스텀SpecificationEvaluator,RepositoryBase<T>상속 세 실행 경로를 비교하고 SQLite xUnit 스모크 테스트로 검증
Meziantou.Framework.TemporaryContainers — 테스트용 임시 컨테이너
- Docker Engine API, Docker/Podman CLI, macOS
container, Windowswslc등 5가지 컨테이너 런타임을 추상화하고ContainerRuntime.Auto가 OS별 우선순위로 자동 탐지 - Apple
container의 사전 포트 할당,wslc의 재시작 미지원·볼륨 명령 부재 같은 런타임별 차이를 라이브러리가 흡수 ReuseId로 테스트 실행 간 컨테이너를 재사용하고 Redis·PostgreSQL·MongoDB·SQL Server용 사전 구성 헬퍼와GetConnectionString()제공
