한 주 동안 .NET 생태계에서 있었던 주요 이슈와 아티클, 기술 트렌드를 정리해 소개합니다.
.NET 11 vs .NET 10 실제 프로덕션 앱 벤치마크 — 업그레이드해야 할까
- 저자: Randhir Jassal
- 태그: dotnet10 #dotnet11 #benchmark
주요 내용
- Mattrx(95K LOC, 11만 MAU, 피크 3,200 req/s SaaS)를 대상으로 .NET 9→10→11 벤치마크
- BenchmarkDotNet + dotnet-counters + 프로덕션 메트릭으로 측정
- .NET 9→10: 처리량 +11%, p95 132→120ms, Working Set 415→380MB, AOT 콜드 스타트 84→61ms
- .NET 10→11(preview): 처리량 +6~9%, p95 -5~7%
- DATAS GC, 리전 기반 GC, JIT 자동 벡터화, AOT 개선이 주요 성능 드라이버
- 결론: LTS인 .NET 10은 즉시 업그레이드, .NET 11은 파일럿만
Interval이 본질이다 — .NET에서 범위 타입을 일급 도메인 객체로 모델링하기
- 저자: Ricardo Groß
- 태그: #ddd #efcore #postgresql
주요 내용
- StartDate/EndDate 두 컬럼 분리의 문제: 경계 의미론(inclusive/exclusive) 암묵적, null 일관성 부재, 겹침 검사 로직 산재
- PostgreSQL의
daterange/int4range네이티브 range 타입과 GiST EXCLUDE 제약을 모델링 출발점으로 제시 CodoMetis.ValueRanges라이브러리: EmptyRange/Finite/UnboundedStart/UnboundedEnd/Infinity의 sealed variant 계층- Contains/Overlaps/IsAdjacentTo/Intersect/Union/Except 등 메모리 내 interval 대수 + RangeSet 정규화
CodoMetis.ValueRanges.EFCore.PostgreSQL로 LINQ → PostgreSQL@>등 연산자 자동 변환
프로덕션의 동적 LINQ — 망하지 않는 런타임 쿼리 파싱 구축기
- 저자: Mario Alberto Arce
- 태그: linq #dynamicquery #performance
주요 내용
- Dynamic LINQ의 보안 위협(인젝션, 임의 코드 실행) 방지 전략
- ConcurrentDictionary 기반 컴파일된 표현식 캐싱
- 프로퍼티 화이트리스트와 위험 토큰(
new/typeof/세미콜론) 차단 - 타입 안전 fluent 쿼리 빌더 패턴
- 순진한 Dynamic LINQ는 10~20배 느림 → 최적화 시 15% 오버헤드의 정량 비교
Entity Framework Repository Pattern이란 무엇인가
- 저자: Chris Pietschmann
- 태그: #efcore #repositorypattern #architecture
주요 내용
- Repository 패턴의 정의와 EF Core가 이미 제공하는 unit-of-work·repository 추상화 비교
- 반복 쿼리 중앙화, 비즈니스 인터페이스, 테스트 용이성이 실제 가치
- 모든 엔티티에 제네릭 저장소를 두는 안티패턴 비판
- Product 엔티티,
IProductRepository, DI 등록, 사용 전후 서비스 코드 비교 - "추상화는 실제 문제를 해결할 때만 유용하다"는 원칙
스레드 풀에서 저지연으로 작업을 스케줄링하려면?
- 저자: Raymond Chen
- 태그: #win32 #threading #latency
주요 내용
- 하드웨어 장치 데이터를 20ms 내 처리해야 하지만 표준 스레드 풀에서 100ms 지연 발생 사례
- “스레드 풀은 throughput용이지 latency용이 아니다” — 데드라인 메커니즘 부재
- 해결책 1:
CreateThreadPool()로 비공개 스레드 풀을 만들어 다른 작업과 격리 - 해결책 2 (C# 권장): BCL의 커스텀 스레드 풀 미지원 한계로 큐+lock 기반 전용 워커 스레드 패턴
- 해결책 3 (C++):
std::queue+ condition variable 패턴
C# 13의 Lock — lock(obj)를 System.Threading.Lock으로 교체
https://medium.com/@pankaj.ikhar/lock-in-c-13-replacing-lock-obj-with-something-better-4bb0c9631491
- 저자: Pankaj Ikhar
- 태그: #csharp13 #threading #lock
주요 내용
- 기존
lock(object)패턴의 문제: 타입 모호성, 락 객체 의도치 않은 노출, 의도 불명확 System.Threading.Lock타입은 컴파일러가 전용 Lock 타입만 사용하도록 강제- 비경합 경로에서 Monitor 대신 Lock.Enter/Exit를 emit하여 오버헤드 감소
EnterScope()API는IDisposable스코프 반환으로 예외 시에도 해제 보장- async 컨텍스트에서는 await 불가,
SemaphoreSlim(1,1)로 대체 필요
ExecuteUpdateAsync — EF Core 최고의 기능 중 하나
- 저자: Ravikumar Makwana
- 태그: #efcore #performance #bulkoperations
주요 내용
- EF Core 7+의
ExecuteUpdateAsync는 엔티티를 메모리에 로드하지 않고 직접 SQL UPDATE 실행 - 25만 건 비활성 사용자 처리 같은 대량 작업에서 메모리/라운드트립 절감
- LINQ 람다 식이 SQL 표현식으로 변환되어 DB 측에서 계산 수행
ExecuteDeleteAsync도 동일 패턴- 사용 금지 케이스: 도메인 이벤트 트리거, 검증 로직 의존, 복잡한 객체 그래프 처리 시
NuGet 버전 복붙 멈춰라 — .NET 중앙 패키지 관리(CPM) 가이드
- 저자: Oluwagbemileke Oyeyoade
- 태그: #nuget #cpm #packagemanagement
주요 내용
- 중대형 솔루션의 버전 드리프트 문제와
Directory.Packages.props로 단일 진실 소스화 - NuGet 6.2 / .NET SDK 6.0.300+,
ManagePackageVersionsCentrally속성으로 활성화 GlobalPackageReference,VersionOverride, 추이적 종속성 핀, 계층적 CPM 등 고급 기능- 마이그레이션 5단계: props 생성, csproj 감사, 항목 채우기, Version 속성 제거, NU1010/NU1008 해결
- 알파벳 정렬, XML 주석 그룹핑,
VersionOverride를 기술 부채로 추적하는 베스트 프랙티스
Microsoft Entra ID·.NET·Graph로 설정 가능한 토큰 수명 적용
- 저자: Damien Bowden
- 태그: #entraid #security #msgraph
주요 내용
- Microsoft Entra ID의 설정 가능한 토큰 수명 정책을 .NET 콘솔 앱으로 구현
- 위임된 사용자 자격증명과 애플리케이션 클라이언트 자격증명 두 방식 제시
TokenLifetimePolicyService클래스로 서비스 주체 검색, 정책 정의, 생성/할당 처리- 토큰 수명을 분 단위(10~1440)로 설정해 보안 위험 감소
- Microsoft Graph API를 통한 정책 생성·할당 절차와 GitHub 저장소 제공
2026년 .NET에서 Vertical Slice Architecture로 프로덕션 앱 구성하기
- 저자: Anton Martyniuk
- 태그: #architecture #verticalslice dotnet
주요 내용
- 기술 레이어가 아닌 기능/유스케이스 단위 프로젝트 구성
- 슬라이스당 4-파일 패턴(Endpoint/Handler/Mapping/Validators)
- 마커 인터페이스 기반 엔드포인트/핸들러/밸리데이터 자동 등록
- 이벤트와 PublicApi 프로젝트를 이용한 슬라이스/모듈 간 통신
- 예외 대신 Result 패턴으로 비즈니스 에러 처리
EF Core 성능 실수 10가지 — 300~500배 차이를 만드는 안티패턴
- 저자: Mukesh Murugan
- 태그: #efcore #performance dotnet10
주요 내용
- N+1 쿼리, 전체 엔티티 반환,
AsNoTracking미사용 등 10가지 흔한 실수 정리 - Cartesian explosion 방지를 위한
AsSplitQuery()활용 - 대량 작업에서
ExecuteUpdateAsync사용으로 300~500배 성능 개선 사례 - Lazy Loading이 JSON 직렬화 중 숨은 쿼리를 트리거하는 패턴 경고
- 컴파일된 쿼리, 인덱스 부재, 페이지네이션 누락 등 실무 체크리스트와 결정 매트릭스
가벼운 읽을거리
후보 항목 중 이슈로 선정되지 않은 가벼운 읽을거리들
EF Core BulkMerge Upsert — 50K행 벤치마크 2.5배 개선
- EF Core 10에도 기본 upsert가 없는 현황과 SQL Server T-SQL MERGE / Entity Framework Extensions의 BulkMerge 방식
- 50,000행 벤치마크: 수동 2,123ms vs BulkMerge 822ms,
ColumnPrimaryKeyExpression미설정 시 모든 레코드가 신규로 취급되는 함정
IValidateOptions로 시작 시점 설정 검증
IOptions<T>가 잘못된 설정을 조용히 기본값으로 받는 문제를IValidateOptions<T>+ValidateOnStart()로 시작 시점OptionsValidationException발생으로 차단- 데이터 주석으로 표현 불가능한 크로스 프로퍼티 검증과 명명된 옵션별 다른 검증 규칙 지원
MSIX의 세 번째 규칙 — 패키지 ID 고유성
- 패키지 ID는 시공간을 통틀어 고유해야 하며 바이너리 내용과 1:1 대응, 비트 변경 시 새 ID 필요
- 동일 ID + 다른 내용 시도 시
ERROR_PACKAGE_ALREADY_EXISTS(0x80073CFB) 발생, 배포 엔진은 동일 ID 패키지가 있으면 staging 건너뜀
HotChocolate GraphQL에 GROUP BY 추가하기
Community.HotChocolate.Data.Grouping라이브러리로 IQueryable에[UseGrouping]적용, 스키마 레벨 타입 안전성 보장- key/having/where 절과 avg/sum/min/max 집계, 인메모리·EF Core·MongoDB 등 다중 소스 호환
.NET 11의 KillOnParentExit — 자식 프로세스 자동 종료
- 블로그 에디터가 Statiq 사이트 빌더를 자식으로 띄우고 종료된 뒤 자식 프로세스가
bin폴더를 잠그는 문제 ProcessStartInfo.KillOnParentExit한 줄 추가로 부모 종료 시 자식 자동 종료 — 기존 Job Object P/Invoke 대체
Visual Studio 2026 테마 커스터마이징
- VS 2026 (18.7)에서 Fluent 디자인 기반 테마 색상 토큰을 Tools > Options > Visual Experience에서 실시간 편집
- JSON 오버라이드를
%LOCALAPPDATA%\Microsoft\VisualStudio\18.0_*\ColorThemes에 배치해 공유, “Blue Steel” 레트로 테마팩 제공
dotnet-cleanup v2 — bin/obj/node_modules 정리 도구
- 솔루션/프로젝트 파일 해석 대신 glob 패턴(
--path,--exclude) 기반으로 재설계 - 삭제 전 임시 폴더로 이동 후 실제 삭제하는 속도 최적화, preview/
--noop/CI용--yes옵션 지원