한 주 동안 .NET 생태계에서 있었던 주요 이슈와 아티클, 기술 트렌드를 정리해 소개합니다.
.NET 11 Performance Edition
- 저자: Steven Giesel
- 태그: #dotnet11 #performance #benchmarkdotnet
주요 내용
- Enum.Equals의 박싱 제거(제네릭 메서드 활용)로 8.39ns→1.21ns, 약 86% 성능 향상
- Vector/Span 관련 불필요한 경계 검사 제거로 약 10% 속도 개선 및 코드 크기 감소
- TimeZone 연간 규칙 캐싱으로 DateTime.Now가 34.54ns→17.93ns로 약 50% 단축
- Guid 파싱의 DecodeByte 로직 개선으로 모든 파싱 메서드가 약 20~25% 빨라짐
- LINQ Min/Max에 SIMD 벡터 셔플 기법 적용, byte/short 연산 최대 75% 개선
Task.WhenAll 잘못 쓰지 마세요 — 5만 개 작업에서 16개 워커로
https://medium.com/@vikpoca/stop-using-task-whenall-like-this-15f710ee38a6
주요 내용
- Task.WhenAll이 완료 집계만 담당하고 동시성 제어는 하지 않아 5만 개 요청이 그대로 동시 실행되는 문제
Parallel.ForEachAsync(MaxDegreeOfParallelism=16)로 균일 작업을 제한하는 방법Channel.CreateBounded(용량 100) 기반 생산자-소비자 파이프라인으로 백프레셔 처리_peakInFlight카운터로 동시 진행 작업 수를 진단하는 코드- 캐시 조회/HTTP 요청/SQL 업데이트별로 부하가 다르므로 직접 측정을 권장
탈취를 스스로 제한하는 로테이팅 리프레시 토큰과 재사용 탐지
- 저자: Ivan Ball-llovera
- 태그: jwt #refreshtoken #security
주요 내용
- 폐기 불가능한 상태비저장 JWT는 단명해야 하고 이것이 리프레시 토큰을 필요로 한다는 상충 관계
- 사용자당 서버 저장 리프레시 토큰(64바이트 난수)을 매 로그인/갱신마다 로테이션하는 설계
- 저장된 토큰과 요청 토큰 불일치 시 전체 세션을 무효화하는 재사용 탐지 코드
- 단일 활성 세션, 경쟁조건으로 인한 오탐, 매 갱신마다 DB 쓰기 필요 등 4가지 트레이드오프 명시
- 액세스 토큰 단명화부터 불일치 시 즉시 폐기까지 5단계 적용 절차
C#으로 데이터셋 분산팽창계수(VIF) 계산하기
- 저자: James McCaffrey
- 태그: csharp #machinelearning #statistics
주요 내용
- 다중공선성(multicollinearity) 문제와 이를 탐지하는 VIF 지표의 수학적 정의
- VIF = 1.0 / (1.0 - R2) 공식과 각 컬럼을 종속변수로 삼아 선형회귀로 R2를 구하는 절차
- R2(결정계수) 계산 방식을 SSres/SStot 기반 예시 수치로 단계별 시연
VarInfFactor(),LinearRegressor클래스 등 C# 콘솔 앱 전체 구현 코드- 정상 데이터셋(VIF 1~1.5대)과 상관관계 주입 데이터셋(VIF 수백만대) 비교 결과
모던 C# URI 처리 — 절대/상대/쿼리/프래그먼트 URL
주요 내용
UriKind.RelativeOrAbsolute로 구성 후IsAbsoluteUri확인이 필요한 이유와 Query/Fragment가 상대 URI에서 예외를 던지는 문제- Scheme, Authority, AbsolutePath, Query, Fragment, PathAndQuery 등 URI 구성 요소 정리
Uri(baseUri, relativeUri)생성자를 이용한 상대→절대 변환과 베이스 URI 후행 슬래시의 영향MakeRelativeUri()를 이용한 절대→상대 변환과 스킴/호스트 불일치 시 원본이 그대로 반환되는 함정Uri.TryCreate()와 nullable 반환 확장 메서드로 예외 없는 처리 제안
Fetch Metadata HTTP 헤더 이해하기 — Sec-Fetch-Site와 그 동료들
- 저자: Andrew Lock
- 태그: aspnetcore #security #httpheaders
주요 내용
- Sec-Fetch-Dest, Sec-Fetch-Site, Sec-Fetch-Mode, Sec-Fetch-User 네 가지 헤더의 의미와 값 체계
- Sec-Fetch-Site의 cross-site/same-origin/same-site/none 네 값의 판정 기준(스킴·도메인·포트·서브도메인)
- 주소창 직접 입력, fetch() 호출, 이미지 로드 등 실제 요청 시나리오별 헤더 값 예시
- .NET 11에서 이 헤더들을 CSRF 방어의 추가 계층으로 활용할 예정이라는 예고와 “Resource Isolation Policy” 구성 방향
모듈을 gRPC 서비스로 추출하기, 라이브로
https://medium.com/@ivanball76/extracting-a-module-to-a-grpc-service-live-799926cf8a32
- 저자: Ivan Ball-llovera
- 태그: #grpc #microservices dotnet #architecture
주요 내용
- "전송 방식은 경계에서만 결정되어야 한다"는 원칙 아래 IMessageBus 인터페이스로 모듈 간 통신 추상화
- .Contracts 프로젝트에서 proto 파일을 자동 컴파일하고 gRPC 어댑터로 기존 인터페이스 재사용
- JWT 전달과 Polly 복원력 파이프라인을 gRPC 통신 계층에 통합
- 설정 변경만으로 InProcessMessageBus에서 RabbitMQ/Azure Service Bus 기반 BrokerMessageBus로 전환
- 여러 배포 단위, 게이트웨이, 서비스 디스커버리 등 운영 복잡성 증가를 함께 지적
오래된 Windows 로케일에 발목 잡히지 않는 법
- 저자: Jeremy Davis
- 태그: windows #locale #dateparsing
주요 내용
- 로컬 Windows 11에서는 정상 동작하지만 프로덕션 Windows Server 2019에서 “September” 날짜 파싱이 일관되게 실패
- 2021년 ISO/CLDR 표준 변경으로 “Sep"→"Sept” 축약형이 바뀌었으나 구버전 Windows에는 미반영돼 OS 간 로케일 데이터 불일치 발생
- PowerShell로 두 OS의 AbbreviatedMonthNames 배열을 비교해 원인 진단
- 런타임에 커스텀 CultureInfo를 생성·수정해 두 OS 모두에서 파싱 가능하도록 대응
Duende를 OIDC 서버로 사용해 ASP.NET Core Identity 애플리케이션에 SAML을 외부 Provider로 구현하기
- 저자: damienbod
- 태그: #saml #oidc #duendeidentityserver
주요 내용
- 웹 클라이언트(OIDC만 인지)–Duende IdentityServer(OIDC 게이트웨이)–Entra ID(SAML)로 이어지는 3계층 아키텍처
- Sustainsys.Saml2.AspNetCore2 패키지를 이용한 SAML 클라이언트 설정과 Entra ID Enterprise Application 메타데이터 매칭
LoadIdentityProviderMetadata헬퍼로 Entra ID federation 메타데이터를 로드하는 방법- Challenge 요청 시작부터
/ExternalLogin/Callback리다이렉트까지 인증 흐름 - OIDC 사용 불가 시에만 SAML을 대체 수단으로 써야 한다는 제약 조건
Docker Desktop 없이 .NET 10 스택 실행하기 — WSLC와 Compose
- 저자: Yovanny Rodríguez
- 태그: dotnet10 #wsl #docker
주요 내용
- Microsoft WSL Container(WSLC)에 Compose 네이티브 지원이 없는 한계를 오픈소스 wslc-compose로 보완
- .NET 10 ASP.NET Core API, PostgreSQL 17, Redis 7.4로 구성된 3-서비스 스택을 compose.yaml과 Multi-stage Dockerfile로 구현
- EF Core DbContext, Redis 캐시 흐름(캐시 미스 시 DB 조회 후 10분 TTL 저장), 환경변수 분리 처리 등 구체적 코드
- WSL 설치부터 마이그레이션 실행, curl 테스트까지 실습 단계
- Docker Desktop 대비 WSLC의 강점과 한계(프로덕션 호환성, 고급 Compose 기능)
macOS에서 .NET Broken Pipe / SSL 에러 디버깅하기
https://medium.com/@preetinderblogger2026/debugging-net-broken-pipe-ssl-errors-on-macos-b3835578da47
주요 내용
- “SSL connection could not be established”/“Broken pipe” 에러를 NuGet/TLS 문제와 애플리케이션 HTTPS 호출 문제로 구분해 진단
- dotnet restore/build/test/run, curl, openssl s_client 등을 이용한 10단계 체계적 진단 절차
- HTTP/2 및 IPv6 비활성화 환경변수, 최소 NuGet.Config, 프록시 설정 제거 등 구체적 조치
- 보안 소프트웨어(방화벽/백신)의 영향과 로컬 개발 인증서 갱신, 네트워크 격리 테스트
YARP로 구현하는 멀티테넌트 API 게이트웨이 — 재배포 없는 동적 라우팅
- 저자: Shanavas Abdul Samad
- 태그: #yarp #apigateway #multitenancy
주요 내용
- DB를 진실의 원천으로 삼고 게이트웨이 인메모리 라우팅 테이블을 원자적으로 교체하는 아키텍처
AddReverseProxy().LoadFromMemory()와IHostedService기반 30초 주기 라우팅 갱신 서비스- 호스트명/헤더/JWT 클레임으로 테넌트를 식별해
X-Tenant-Id헤더를 전파하는 미들웨어 - 설정 검증 실패 시 이전 라우팅 테이블 유지, 인플라이트 연결 드레인 등 운영 주의점
- 온보딩 속도, 전용 풀 테넌트, 점진적 마이그레이션 등 3가지 적용 시나리오
.NET 캐싱 생존 가이드
https://truestorydavestorey.medium.com/cache-me-if-you-can-a-net-caching-survival-guide-200558945ffa
- 저자: Dave Storey
- 태그: dotnet #caching #distributedsystems
주요 내용
- Cache-Aside, 사전 새로고침, Read/Write-Through, L1/L2 이중 캐싱 등 캐싱 전략 분류
- IMemoryCache 설정 코드(AbsoluteExpirationRelativeToNow, SlidingExpiration) 예시
- 캐시 폭증(Cache Stampede), 원자성 없는 확인 로직, 분산 노드 불일치, Poison Pill 등 6가지 실무 함정
- IMemoryCache/LazyCache/HybridCache(.NET 9+)/FusionCache를 특징별로 비교
시간적 결합이란 무엇이며 어떻게 다룰 것인가
https://medium.com/@vosarat1995/temporal-coupling-what-is-it-and-how-to-deal-with-it-5de64ee2f2ec
- 저자: Egor Tarasov
- 태그: csharp #cleancode #refactoring
주요 내용
- 시간적 결합(Temporal Coupling)을 "암묵적인 연산 순서에 대한 기대치"로 정의
- 런타임 예외 명시화 → 리프 서비스 상태 제거 → 중간 서비스 stateless화 → 호출부 갱신 → 불변 레코드 도입의 5단계 리팩토링
- 문제가 있는 원본 코드부터 리팩토링 완성본까지 전체 C# 소스를 단계별로 제공
- 불변성과 순수 함수 기반 설계로 구조적으로 버그가 불가능한 상태를 달성하는 결론
가벼운 읽을거리
후보 항목 중 이슈로 선정되지 않은 가벼운 읽을거리들
ILSpy 11.0 Preview 1 — WPF에서 Avalonia로 전환
- WPF UI를 걷어내고 Avalonia 12 기반으로 전환해 Windows 외에 Linux/macOS에서도 빌드·실행 가능
- 북마크, 옴니바 검색바, NuGet 피드 탐색 등 신규 기능과 동적 표현식 await 디컴파일 등 개선
Remove Is Not Uninstall
- MSIX 패키지 생명주기를 Stage → Register → Deregister → Destage 4단계로 정의
- "Remove"는 Deregister를 보장하지만 페이로드 삭제(Destage)는 다른 사용자의 사용 여부에 따라 조건부
.NET의 NLog 타겟 — File, Database, Console, Custom
- File, Console, Database, Network, Null 등 내장 타겟과 Seq, Elasticsearch 등 서드파티 통합
- AsyncWrapper로 파일 I/O를 백그라운드 큐로 옮겨 블로킹 방지, NLog 5.x/6.x API 차이(concurrentWrites 옵션 제거 등)
OpenIddict 클라이언트 인가 요청에 커스텀 파라미터 전달하기
- OpenIddict.Client 사용 시 PrepareAuthorizationRequestContext 이벤트에서 파라미터를 직접 설정하는 방법
- 기본 OpenIdConnect 핸들러 사용 시 OnRedirectToIdentityProvider 이벤트로 값을 추가하는 방법
dotMorten/SideKick — E-Ink 대시보드 워커 앱
- FT232H USB 어댑터로 Waveshare 전자종이 디스플레이를 구동하는 .NET Worker 기반 애플리케이션
- 캘린더, Microsoft Graph, Todoist, GitHub 등 다양한 소스를 연동하는 WinUI 단일 프로젝트 MSIX 패키징 구조
모듈러 모놀리스 우선 — 왜 첫날부터 마이크로서비스를 이기는가
- "초기에는 서비스 경계를 알 수 없다"는 문제 정의와 모놀리스 내 경계 변경 비용 대 마이크로서비스 간 변경 비용 비교
- Contracts/Internal 네임스페이스 분리와 컴파일러 강제 경계(internal 접근 제어자), 아키텍처 테스트로 경계 위반 감지
