Skip to content

필사 모드: 모던 .NET 2026 — .NET 9 / .NET 10 LTS / Aspire / Blazor United / MAUI / Avalonia 11 / FastEndpoints 심층 가이드

한국어
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.
원문 렌더가 준비되기 전까지 텍스트 가이드로 표시합니다.

프롤로그 — "Java가 아닌 또 하나의 엔터프라이즈"

2026년 5월. 어떤 시니어 엔지니어가 농담처럼 말했다. ".NET을 안 쓴다고 말하는 사람은 많지만, 자기 카드사 백엔드가 .NET 위에서 돌고 있다는 걸 모르는 사람도 많죠." 농담이지만 진심이 절반 정도 섞여 있다.

웹 트렌드 컨퍼런스의 무대 위는 여전히 TypeScript, Go, Rust가 차지하지만, 실제로 결제·은행·제조·공공·게임 백엔드의 한 축은 .NET이다. 그리고 .NET 본인도 2020년 .NET 5 통합 이후 매년 11월마다 새 메이저를 내며 부지런히 모양을 바꿔왔다.

2024-2026년 사이에 일어난 일을 정리하면:

- **.NET 9 (2024년 11월)** — STS(Standard Term Support, 18개월). 성능·CLR 개선 중심.

- **.NET 10 (2025년 11월, LTS)** — Long Term Support 3년. 새로운 기본값.

- **ASP.NET Core 10** — Minimal API의 성숙, OpenAPI 내장.

- **Aspire (2024년 11월 GA)** — 클라우드 네이티브 오케스트레이션 + 텔레메트리.

- **Blazor United** — Server / WASM / SSR / streaming을 하나의 모델로.

- **.NET MAUI** — 안정화. iOS/Android/Mac/Windows 단일 코드.

- **Avalonia 11** — Linux 포함 진정한 크로스 플랫폼 데스크탑.

- **EF Core 9** — JSON, complex types, primitive collections.

- **C# 13 (2024)** — params collections, lock object, escape sequences.

- **C# 14 (2025)** — field accessor, partial members, null-conditional assignment.

이 글은 **2026년 .NET 진영의 지도**를 한 번에 정리한다. 어떤 버전을 골라야 하나, ASP.NET Core 10과 FastEndpoints 중 무엇을 쓰나, Aspire는 정말 필요한가, MAUI vs Avalonia 11, EF Core vs Dapper, MediatR이 유료화된 뒤의 CQRS 패턴, NativeAOT의 실제 한계 — 그리고 누가 .NET을 골라야 하는가까지.

먼저 한 가지만 미리 말해두자. **.NET은 죽지 않았다.** 그리고 죽기는커녕, 한국·일본의 enterprise·금융·정부 시스템에서는 오히려 점점 더 깊이 자리 잡고 있다. JVM·Go·Node와는 다른 결의 도구이고, 그 결이 잘 맞는 도메인이 분명히 존재한다.

1장 · 2026년 .NET 지도 — 한 장의 그림

| 영역 | 2026년의 사실상 표준 | 비고 |

| --- | --- | --- |

| 런타임 | **.NET 10 LTS** (2025-11) | .NET 9는 2026-05 EOL 임박 |

| 언어 | C# 13 / C# 14 | F# 9, VB는 stable 유지 |

| 웹 백엔드 | ASP.NET Core 10 + Minimal APIs | + FastEndpoints / Carter |

| 데이터 | EF Core 9 / Dapper / Marten | 선택 폭 큼 |

| 메시징 | MassTransit / NServiceBus / Wolverine | MediatR 유료화 영향 큼 |

| CQRS | Wolverine / Brighter / 직접 구현 | MediatR 8.x는 paid |

| 클라우드 오케스트레이션 | **.NET Aspire** | Bicep + OTel 내장 |

| 웹 UI | **Blazor United** | Server + WASM + SSR |

| 모바일 / 데스크탑 | .NET MAUI | iOS/Android/Mac/Win |

| 크로스 플랫폼 데스크탑 | **Avalonia 11** | Linux 포함 |

| 게임 | Unity (.NET 8 기반), Stride, MonoGame | Unity는 자체 런타임 |

| 배포 | Container + NativeAOT | self-contained 줄어듬 |

| 패키지 | NuGet 6 + Central Package Management | global.json 표준화 |

| 분석 | Roslyn analyzers + StyleCop + Sonar | nullable enforcement |

핵심만 골라 한 줄로 요약하면:

- **런타임의 자리는 .NET 10 LTS로 굳었다.** .NET 9는 짧게 쓰고 떠나는 STS다.

- **웹은 Minimal APIs가 default가 되었지만**, FastEndpoints / Carter가 "조금 더 구조적인 Minimal API"로 자리 잡았다.

- **Aspire는 .NET 진영의 docker-compose + Kubernetes + OpenTelemetry 통합 도구**가 되었다.

- **UI는 셋으로 갈라졌다.** 웹은 Blazor United, 모바일/데스크탑은 MAUI, Linux 포함 진정한 크로스 플랫폼은 Avalonia 11.

- **CQRS 진영은 MediatR 유료화 이후 Wolverine / Brighter / 직접 구현**으로 흩어졌다.

2장 · .NET 10 LTS (2025-11) — 플래그십 릴리스

.NET 10은 2025년 11월에 GA가 됐고, Long Term Support 3년이다. 즉 2028년 11월까지 패치 지원. .NET 6 (2021-11), .NET 8 (2023-11) 다음으로 오는 정식 LTS이며, .NET 9는 그 사이의 STS였다.

핵심 변경점:

- **CLR / GC**: DATAS(Dynamically Adapting To Application Sizes) GC가 default로. 메모리 footprint가 작은 서비스에서 30-40% 줄어듬.

- **JIT**: PGO(Profile-Guided Optimization) on by default. devirtualization과 inlining이 한 단계 더 적극적.

- **NativeAOT 성숙**: 더 많은 framework 라이브러리가 AOT-safe. ASP.NET Core minimal API + EF Core 일부가 AOT 가능.

- **JSON**: System.Text.Json이 polymorphism, snake_case naming, IAsyncEnumerable streaming을 정식 지원.

- **threading**: TimeProvider, PriorityQueue 개선. async LINQ가 stable.

- **C# 14 동시 발매**: field accessor, partial properties/methods, null-conditional assignment.

- **NuGet 6 + Central Package Management**: 솔루션 전체의 패키지 버전을 Directory.Packages.props 하나로 통일.

- **dotnet CLI 통합**: `dotnet run app.cs` 단일 파일 실행이 정식 지원.

LTS의 의미는 단순히 패치 기간이 길다는 것이 아니라, **에코시스템 라이브러리가 가장 잘 따라온다**는 것이다. EF Core 10, ASP.NET Core 10, Aspire의 안정 채널, MassTransit, MediatR fork들 — 거의 모든 메이저 라이브러리가 .NET 10을 first-class target으로 잡고 있다.

업그레이드 권장:

- .NET 6 (LTS, 2024-11 EOL): 즉시 .NET 10으로.

- .NET 8 (LTS, 2026-11 EOL): 천천히 .NET 10으로. EF Core, MediatR 등 라이브러리 호환성 체크 후.

- .NET 9 (STS, 2026-05 EOL): 빨리 .NET 10으로. 어차피 곧 끝난다.

3장 · .NET 9 (2024-11) — STS와의 비교

.NET 9는 STS, 즉 18개월 지원이라 2026년 5월에 끝난다. 이 글이 쓰이는 시점이 정확히 그 무렵이다. .NET 9는 "다음 LTS인 .NET 10을 위한 실험판" 같은 역할을 했다.

.NET 9에서 들어왔다가 .NET 10에서 다듬어진 것들:

- **DATAS GC** — .NET 9에서 opt-in, .NET 10에서 default.

- **System.Text.Json polymorphism** — .NET 9에서 alpha, .NET 10에서 stable.

- **OpenAPI 내장** — .NET 9에서 Swashbuckle 의존을 떼고 `Microsoft.AspNetCore.OpenApi`로 들어왔으나, .NET 10에서 UI까지 통합.

- **Kestrel HTTP/3** — .NET 9에서 production-ready.

- **NativeAOT 확장** — .NET 9에서 더 많은 라이브러리 지원.

요점: **.NET 9를 운영하는 팀은 2026년 중반까지는 .NET 10으로 이동**해야 한다. 8 (LTS)로 돌아가는 건 의미가 없다 — .NET 8도 2026년 11월에 끝난다.

LTS / STS의 패턴은 이제 분명하다:

- **LTS** — 짝수 메이저(8, 10, 12...), 3년 지원, 엔터프라이즈 기본값.

- **STS** — 홀수 메이저(7, 9, 11...), 18개월, 빠른 실험.

엔터프라이즈는 STS를 건너뛰는 게 일반적이다. 즉 .NET 6 → 8 → 10이 정상 경로다.

4장 · C# 13 / C# 14 — params collections, field accessor

C#은 매년 11월 .NET과 같이 새 메이저를 낸다. C# 13은 2024년, C# 14는 2025년에 .NET 10과 함께 발매됐다.

**C# 13의 핵심**:

- **params collections** — `params Span<int>`, `params IEnumerable<int>` 등 컬렉션 타입에 params 가능. 더 이상 `params int[]`만이 답이 아니다.

- **lock object 전용 타입** — `System.Threading.Lock`이 들어와 `lock(myLock)`에 적합한 모나딕 사용. 일반 object를 lock으로 쓰는 패턴을 분석기가 경고.

- **새 escape sequence `\e`** — ANSI escape (ESC 0x1B). 터미널 ANSI 색 코드 작성이 깔끔해짐.

- **partial properties** — partial method에 이어 partial property도 가능. source generator 친화.

- **`field` keyword 미리보기** — getter/setter 안에서 backing field에 `field`로 직접 접근.

**C# 14의 핵심**:

- **`field` keyword 정식** — getter/setter 안에서 `field`로 자동 backing field 접근. 명시적 backing field 선언이 사라짐.

- **partial members 확장** — 생성자, 연산자, 인덱서까지 partial 가능.

- **null-conditional assignment** — `obj?.Prop = value` — obj가 null이면 할당 안 함.

- **확장된 nameof** — 미해결 타입 인자를 받아도 nameof 가능.

- **확장 멤버 진화** — 확장 메서드 외에 확장 프로퍼티 미리보기.

`field` 키워드를 한 줄로 보면:

// 전통 방식 — backing field 명시

private string _name = string.Empty;

public string Name

{

get => _name;

set => _name = value?.Trim() ?? throw new ArgumentNullException();

}

// C# 14 — field로 직접

public string Name

{

get;

set => field = value?.Trim() ?? throw new ArgumentNullException();

} = string.Empty;

`_name`을 손으로 선언하지 않아도 컴파일러가 만들어준다. 더 이상 `_camelCase` 백킹 필드의 네이밍 디베이트가 필요 없다.

5장 · ASP.NET Core 10 — performance + DX

ASP.NET Core 10은 .NET 10과 함께 나왔다. 2026년 5월 현재, 모던 .NET 웹의 기본형은 다음과 같다.

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddOpenApi();

builder.Services.AddDbContext<AppDbContext>(opts =>

opts.UseNpgsql(builder.Configuration.GetConnectionString("Default")));

var app = builder.Build();

app.MapOpenApi(); // /openapi/v1.json

app.MapScalarApiReference(); // Scalar UI 통합

app.MapGet("/users/{id:guid}", async (Guid id, AppDbContext db) =>

{

var user = await db.Users.FindAsync(id);

return user is null ? Results.NotFound() : Results.Ok(user);

})

.WithName("GetUser")

.WithOpenApi();

app.MapPost("/users", async (CreateUserDto dto, AppDbContext db) =>

{

var user = new User(dto.Name, dto.Email);

db.Users.Add(user);

await db.SaveChangesAsync();

return Results.Created($"/users/{user.Id}", user);

});

app.Run();

**달라진 점**:

- **OpenAPI 내장** — Swashbuckle을 따로 안 깐다. `Microsoft.AspNetCore.OpenApi`가 default.

- **Scalar UI 통합** — Swagger UI보다 가볍고 깨끗한 OpenAPI viewer.

- **JSON streaming** — IAsyncEnumerable이 chunked transfer encoding으로 자연스럽게 흐름.

- **HTTP/3 default** — Kestrel이 production-ready로 HTTP/3 지원.

- **Compiled routing** — endpoint dispatch가 reflection 대신 compile-time 코드 생성.

- **OpenTelemetry first-class** — `AddOpenTelemetry()`가 표준 패턴.

**성능 수치** (TechEmpower 류 마이크로벤치마크 기준):

- ASP.NET Core 10 Minimal API + Kestrel: 700k+ req/s (Plaintext)

- ASP.NET Core 10 + EF Core 9 + Postgres: 80-100k req/s (Fortunes)

- 동급 Go (net/http): 600k req/s

- 동급 Node (Fastify): 200k req/s

즉 ASP.NET Core는 2026년에도 가장 빠른 메인스트림 웹 프레임워크 중 하나다.

6장 · Aspire (2024-11 GA) — 클라우드 네이티브 오케스트레이션

Aspire는 2024년 11월에 GA가 된 .NET 진영의 클라우드 네이티브 오케스트레이션 + 로컬 개발 환경 + 텔레메트리 통합 도구다. 이름은 거창하지만 본질은 단순하다.

**Aspire가 해결하는 문제**:

- 로컬에서 `docker-compose up` 대신 .NET 코드로 의존성 정의.

- 마이크로서비스 여러 개 + Postgres + Redis + RabbitMQ를 한 솔루션으로.

- OpenTelemetry 자동 주입 + 대시보드 내장.

- 클라우드 배포 시 Bicep / Terraform / Kubernetes 매니페스트 자동 생성.

**AppHost 프로젝트의 모양**:

var builder = DistributedApplication.CreateBuilder(args);

var postgres = builder.AddPostgres("db")

.AddDatabase("appdb");

var redis = builder.AddRedis("cache");

var rabbitmq = builder.AddRabbitMQ("messaging");

var apiService = builder.AddProject<Projects.ApiService>("api")

.WithReference(postgres)

.WithReference(redis)

.WithReference(rabbitmq);

builder.AddProject<Projects.WebFrontend>("web")

.WithReference(apiService);

builder.Build().Run();

이 코드를 `dotnet run`하면:

1. Postgres / Redis / RabbitMQ 컨테이너가 자동으로 뜬다.

2. API 서비스와 Web Frontend가 .NET 프로세스로 시작된다.

3. 연결 문자열은 environment variable로 자동 주입.

4. OpenTelemetry 데이터가 Aspire Dashboard로 흐른다.

5. 분산 trace, log, metric이 한 화면에서 보인다.

**Aspire Dashboard**:

- 분산 trace (waterfall view)

- 구조화된 로그

- 메트릭 (CPU, memory, request rate, latency)

- 컨테이너 / 프로세스 상태

- 환경 변수 inspector

**클라우드 배포**:

- Azure Container Apps에 `azd up` 한 줄로 배포 가능.

- 다른 클라우드는 Aspire 매니페스트 → Kubernetes / Bicep / Terraform 변환.

**도커 컴포즈 vs Aspire**:

| 기준 | docker-compose | Aspire |

| --- | --- | --- |

| 정의 언어 | YAML | C# |

| 디버깅 | 컨테이너 attach | .NET 프로세스 직접 디버깅 |

| 텔레메트리 | 별도 설치 | 내장 |

| 클라우드 배포 | 변환 도구 별도 | 내장 generator |

| .NET 외부 서비스 | 잘 됨 | 잘 됨 (Postgres, Redis, OS image 등) |

Aspire는 .NET 마이크로서비스를 운영하는 팀에게 사실상 default가 됐다. 단, .NET이 아닌 서비스가 많은 폴리글랏 환경이라면 docker-compose가 여전히 자연스럽다.

7장 · Blazor United — Server + WASM + SSR + streaming

Blazor는 2018년의 WebAssembly hype 이후 8년이 지나 2026년 현재, "한 컴포넌트가 여러 렌더링 모드를 골라 쓸 수 있는" 단일 모델로 정착했다. 이를 Microsoft 공식 문서는 Blazor United라고 부른다.

**네 가지 렌더 모드**:

1. **Static SSR** — 서버에서 한 번 그리고 끝. 가장 빠름, 인터랙션 없음.

2. **Streaming SSR** — 비동기 데이터 로딩 결과를 chunked로 스트리밍.

3. **Server interactive** — SignalR 기반, 서버에서 이벤트 처리.

4. **WebAssembly interactive** — 클라이언트 WASM, 오프라인 가능.

한 페이지가 컴포넌트 단위로 모드를 섞을 수 있다.

@page "/dashboard"

@rendermode InteractiveAuto

`InteractiveAuto`는 첫 방문 시 Server 모드(SignalR)로 빠르게 뜨고, WASM 다운로드가 완료되면 그 다음부터는 WASM으로 전환한다. 첫 인터랙션 지연을 줄이는 패턴.

**Blazor의 강점**:

- 풀스택 C#. JavaScript 없이 SPA 가능 (또는 최소화).

- ASP.NET Core와의 통합. 같은 인증, DI, 미들웨어 사용.

- SignalR이 안정적. 양방향 통신이 자연스러움.

- WASM AOT 빌드로 차츰 첫 로드 사이즈 줄어드는 중.

**Blazor의 약점**:

- WASM 초기 번들 크기는 여전히 1-3MB. Compression 적용 후도 무겁다.

- 생태계는 React/Vue에 비해 작다.

- 모바일 브라우저 WASM 성능은 여전히 데스크탑보다 느림.

- 디자이너 / 컴포넌트 마켓이 부족함.

**누가 쓰나**: 사내 도구, B2B 어드민, 풀스택 .NET 팀의 SPA가 sweet spot. 공개 마케팅 사이트나 SEO 중심 페이지는 Static SSR로 한정.

8장 · .NET MAUI — 크로스 플랫폼 네이티브

.NET MAUI(Multi-platform App UI)는 2022년 Xamarin.Forms의 후계자로 나와, 2024-2026년 사이에 안정화됐다. iOS / Android / macOS / Windows를 단일 C# 코드로.

**MAUI의 구조**:

- 단일 프로젝트, 단일 코드베이스.

- XAML 또는 C# 마크업으로 UI.

- 플랫폼별 핸들러로 native control 그림.

- Hot reload 지원.

**MAUI Hybrid + Blazor Hybrid**:

MAUI 안에서 BlazorWebView를 띄워 Razor 컴포넌트를 native 앱으로 재사용 가능. 즉 웹용으로 만든 Blazor UI를 모바일 앱에도 거의 그대로.

이 패턴은 **풀스택 .NET 팀이 모바일 앱까지 갖출 때** 매력적이다. React Native보다 빌드 / 배포 파이프라인이 단순하고, Flutter보다 .NET 백엔드와의 통합이 자연스럽다.

**MAUI의 약점**:

- iOS / Android 네이티브 SDK 진화 속도를 100% 따라가지는 못함.

- Linux 데스크탑은 공식 지원 아님 (커뮤니티 GTK 백엔드 존재).

- 일부 복잡한 애니메이션 / 성능 critical 부분은 여전히 native가 우위.

**2026년 권고**: 사내 모바일 / 윈도우 데스크탑 한정. 공개 앱스토어용 컨슈머 앱은 Flutter, SwiftUI/Compose, React Native와 비교 후 결정.

9장 · Avalonia 11 — 진정한 크로스 플랫폼 UI

Avalonia는 커뮤니티가 만들고 .NET Foundation에서 운영하는 오픈소스 크로스 플랫폼 UI 프레임워크다. 2023년 11월에 11.0이, 2024-2025년에 11.1 / 11.2 / 11.3이 차례로 나왔다.

**MAUI와의 차이**:

| 기준 | .NET MAUI | Avalonia 11 |

| --- | --- | --- |

| 거버넌스 | Microsoft | 커뮤니티 + 상용(AvaloniaUI 회사) |

| 플랫폼 | iOS/Android/Mac/Win | iOS/Android/Mac/Win/**Linux**/WebAssembly |

| 렌더링 | 플랫폼 native 컨트롤 | 자체 렌더링 (Skia 기반) |

| UI 일관성 | 플랫폼마다 다름 | 모든 플랫폼 동일 |

| 디자인 패턴 | XAML + handlers | XAML + 자체 컨트롤 트리 |

| Hot reload | 지원 | 지원 |

| 데스크탑 우선도 | 약함 | 강함 |

**Avalonia가 빛나는 경우**:

- **Linux 데스크탑이 진짜로 필요한 팀**. (MAUI는 못 함.)

- **모든 플랫폼에서 픽셀 단위로 같은 UI**가 필요한 경우.

- **데스크탑 중심 앱** (IDE, 그래픽 도구, 음악/영상 소프트웨어).

**실제 사례**:

- **JetBrains Rider**는 일부 UI에 Avalonia 시도 (전면 채택은 아님).

- **WasabiWallet, Camelot, AvaloniaEdit** 등 오픈소스 .NET 데스크탑 도구.

- **여러 enterprise 사내 도구**가 WPF에서 Avalonia로 이주 중. WPF는 Windows 전용이라 Mac/Linux 클라이언트를 위해.

**약점**:

- 모바일은 가능하지만 native 느낌이 부족함. MAUI에 양보가 맞다.

- WPF 대비 커뮤니티 컨트롤 마켓이 작음.

**2026년 권고**: WPF의 자연스러운 후계자. Linux/Mac 데스크탑 .NET 앱이라면 첫 번째 선택지.

10장 · Entity Framework Core 9

EF Core 9는 2024년 11월에 .NET 9와 같이 나왔고, EF Core 10이 2025년 11월에 나왔다. 2026년 5월의 사실상 표준은 EF Core 10이다.

**최근 2-3년의 변화**:

- **JSON columns 정식 지원** — Postgres `jsonb`, SQL Server JSON, SQLite JSON. LINQ로 JSON 내부 쿼리.

- **Complex types** — owned types를 더 가볍게. Value object 모델링이 자연스러워짐.

- **Primitive collections** — `List<int>`을 컬럼에 그대로 매핑.

- **Bulk operations** — `ExecuteUpdateAsync`, `ExecuteDeleteAsync`로 N+1 없는 일괄 수정.

- **Query splitting 기본값** — JOIN 폭발 방지.

**전형적인 코드**:

public class AppDbContext : DbContext

{

public DbSet<Order> Orders => Set<Order>();

protected override void OnModelCreating(ModelBuilder mb)

{

mb.Entity<Order>(b =>

{

b.ToTable("orders");

b.ComplexProperty(o => o.ShippingAddress);

b.OwnsMany(o => o.Items);

b.Property(o => o.Metadata)

.HasColumnType("jsonb");

});

}

}

// Bulk delete - SQL 한 번

await db.Orders

.Where(o => o.Status == OrderStatus.Cancelled && o.CreatedAt < DateTime.UtcNow.AddYears(-1))

.ExecuteDeleteAsync();

**EF Core vs Dapper vs Marten**:

| 도구 | 모델 | 강점 | 약점 |

| --- | --- | --- | --- |

| **EF Core** | ORM / Change tracking | 풍부한 LINQ, 마이그레이션, 관계 | 복잡 쿼리는 SQL 가독성 떨어짐 |

| **Dapper** | Micro-ORM | 빠름, SQL 직접 작성 | 모든 게 수동 |

| **Marten** | Postgres + Event Sourcing | document DB + event store | Postgres 전용 |

| **LinqToDB** | SQL-shape LINQ | 성능 + LINQ 표현력 | 학습 곡선 |

2026년의 default는 **EF Core + Dapper 혼용**이다. CRUD와 도메인 변경은 EF Core, 무거운 보고 / 분석 쿼리는 Dapper.

11장 · MediatR / MassTransit / NServiceBus — CQRS와 메시징

2024년 말, .NET CQRS 진영이 흔들렸다. **MediatR이 8.x부터 상용 라이선스로 전환**됐기 때문이다. 또한 같은 저자의 AutoMapper도 비슷한 시기에 paid edition을 도입했다. 이 결정은 .NET 커뮤니티에서 큰 논쟁을 일으켰다.

**현재의 선택지**:

| 도구 | 모델 | 라이선스 | 비고 |

| --- | --- | --- | --- |

| **MediatR 8+** | in-process mediator | Commercial | 안정. 비용 발생. |

| **Wolverine** | in-process + messaging | OSS (MIT) | Jeremy D. Miller. CQRS + saga 통합. |

| **Brighter** | command processor | OSS (BSD) | 메시징 통합. |

| **자체 구현** | DI + interface | n/a | 작은 프로젝트는 충분. |

**Wolverine 예시**:

// Handler — interface 없이 메서드 시그니처로 인식

public class CreateOrderHandler

{

public async Task<OrderCreated> Handle(CreateOrder command, AppDbContext db)

{

var order = new Order(command.CustomerId, command.Items);

db.Orders.Add(order);

await db.SaveChangesAsync();

return new OrderCreated(order.Id);

}

}

// 호출

var result = await bus.InvokeAsync<OrderCreated>(new CreateOrder(...));

interface 선언 없이 메서드 시그니처를 분석하는 게 Wolverine의 특징. MediatR의 `IRequestHandler` 보일러플레이트가 사라진다.

**메시징 (out-of-process)**:

| 도구 | 트랜스포트 | 라이선스 | 강점 |

| --- | --- | --- | --- |

| **MassTransit** | RabbitMQ, Azure Service Bus, Kafka 등 | OSS (Apache) → 일부 Pro | 가장 많이 쓰임 |

| **NServiceBus** | 다양 | Commercial | 엔터프라이즈. saga 강함. |

| **Wolverine** | RabbitMQ, Kafka, Azure Service Bus | OSS (MIT) | CQRS와 messaging 통합 |

| **Rebus** | RabbitMQ, Azure Service Bus, etc. | OSS | 가벼움 |

**MassTransit의 saga 패턴**:

public class OrderSaga : MassTransitStateMachine<OrderState>

{

public State Submitted { get; private set; }

public State Paid { get; private set; }

public State Shipped { get; private set; }

public Event<OrderSubmitted> OnSubmitted { get; private set; }

public Event<PaymentReceived> OnPaid { get; private set; }

public OrderSaga()

{

InstanceState(x => x.CurrentState);

Initially(

When(OnSubmitted)

.Then(c => c.Saga.OrderId = c.Message.OrderId)

.TransitionTo(Submitted));

During(Submitted,

When(OnPaid)

.TransitionTo(Paid));

}

}

**2026년 권고**:

- **단순한 in-process mediator**: 직접 구현 또는 Wolverine.

- **CQRS + messaging 통합 필요**: Wolverine.

- **엔터프라이즈 + 상용 지원 필요**: NServiceBus.

- **이미 MediatR + MassTransit 쓰던 팀**: MediatR 8+ 라이선스 비용 계산 후 갈아탈지 결정.

12장 · FastEndpoints / Carter / Minimal APIs

ASP.NET Core 10의 라우팅 스타일은 셋으로 갈렸다.

**1. Minimal APIs (default)**:

app.MapGet("/orders/{id:guid}", async (Guid id, AppDbContext db) =>

{

var order = await db.Orders.FindAsync(id);

return order is null ? Results.NotFound() : Results.Ok(order);

});

장점: 가벼움, 시작이 빠름. 단점: 큰 API에서 Program.cs가 비대해짐.

**2. Controllers (전통)**:

[ApiController]

[Route("orders")]

public class OrdersController : ControllerBase

{

[HttpGet("{id:guid}")]

public async Task<IActionResult> Get(Guid id) { ... }

}

장점: 익숙함, 클래스 단위 조직화. 단점: 보일러플레이트 많음.

**3. FastEndpoints / Carter (구조적 미니멀)**:

FastEndpoints는 "Endpoint per class" 패턴을 강제한다.

public class GetOrderEndpoint : Endpoint<GetOrderRequest, OrderResponse>

{

public AppDbContext Db { get; set; } = null!;

public override void Configure()

{

Get("/orders/{id:guid}");

AllowAnonymous();

}

public override async Task HandleAsync(GetOrderRequest req, CancellationToken ct)

{

var order = await Db.Orders.FindAsync([req.Id], ct);

if (order is null) { await SendNotFoundAsync(ct); return; }

await SendAsync(new OrderResponse(order), cancellation: ct);

}

}

**Carter**는 Nancy의 정신적 후계자로, 모듈 단위 라우팅.

public class OrdersModule : ICarterModule

{

public void AddRoutes(IEndpointRouteBuilder app)

{

app.MapGet("/orders/{id:guid}", async (Guid id, AppDbContext db) =>

{

var order = await db.Orders.FindAsync(id);

return order is null ? Results.NotFound() : Results.Ok(order);

});

}

}

**비교**:

| 기준 | Minimal API | Controllers | FastEndpoints | Carter |

| --- | --- | --- | --- | --- |

| 보일러플레이트 | 매우 적음 | 많음 | 적음 | 매우 적음 |

| 조직화 | 약함 | 강함 | 강함 (per-class) | 중간 (per-module) |

| 성능 | 가장 빠름 | 약간 느림 | 가장 빠름 (Minimal 위) | 가장 빠름 (Minimal 위) |

| OpenAPI | 자동 | 자동 | 자동 + 풍부 | 자동 |

| 학습 곡선 | 낮음 | 낮음 | 중간 | 낮음 |

| 큰 API 친화도 | 약함 | 강함 | 강함 | 중간 |

**권고**: 50개 이하의 엔드포인트는 Minimal API, 그 이상은 FastEndpoints 또는 Controllers. Carter는 가볍게 모듈로 나누고 싶을 때.

13장 · NativeAOT — 작은 단일 실행 파일

NativeAOT는 .NET 7에서 GA가 됐고, .NET 9-10에서 성숙했다. 핵심 아이디어는 **JIT 대신 ahead-of-time 컴파일로 단일 native 실행 파일을 생성**하는 것이다.

**장점**:

- **시작 시간**: 보통 50-100ms (vs JIT의 200-500ms). cold start 민감한 워크로드에 좋다 (serverless, CLI 도구).

- **메모리**: 30-40% 작음. JIT 관련 메타데이터 없음.

- **단일 실행 파일**: 10-30MB의 stand-alone binary. CoreCLR / framework 동봉 안 함.

- **트림된 바이너리**: 사용 안 하는 코드 제거.

**제약**:

- **Reflection 제한**: 전통적인 reflection-heavy 라이브러리는 동작 안 함. Serializer, ORM, IoC container가 모두 source generator를 써야 함.

- **dynamic 코드 생성 금지**: Reflection.Emit이 작동 안 함.

- **JIT compilation 없음**: 런타임에 새 어셈블리 로드 불가.

**AOT-친화 라이브러리**:

- System.Text.Json (with source generator)

- Minimal APIs / FastEndpoints

- EF Core 일부 (8+부터 점진적)

- Dapper

- Refit (HTTP client)

- ASP.NET Core RequestDelegateGenerator

**AOT-비친화**:

- 일부 IoC 컨테이너 (Autofac, Castle Windsor 등)

- Newtonsoft.Json (Reflection 의존)

- MediatR 일부 패턴

- AutoMapper

**예시 — AOT minimal API**:

dotnet publish -c Release -r linux-x64

단일 native 실행 파일 → bin/Release/net10.0/linux-x64/publish/MyApi

사이즈: 보통 15-25 MB

**언제 쓰나**:

- AWS Lambda, Cloud Functions 등 serverless.

- CLI 도구 (dotnet-tool 대안).

- 컨테이너 cold start 민감한 마이크로서비스.

- 시작 시간이 비즈니스적으로 중요한 모든 곳.

**언제 안 쓰나**:

- Reflection 의존 라이브러리가 많은 레거시.

- 빌드 시간 / 디버깅 편의가 우선인 개발 단계.

- LegacyEF Core / 복잡한 IoC 컨테이너를 쓰는 모놀리스.

14장 · Roslyn analyzers / NuGet / dotnet CLI

**Roslyn analyzers**:

.NET 분석기는 컴파일 시점에 코드 품질·보안·성능 이슈를 잡는다. 2026년에는 거의 default로 다음을 깐다:

- **.NET 내장 분석기** (CA, IDE 룰)

- **StyleCop.Analyzers** (코드 스타일)

- **SonarAnalyzer.CSharp** (정적 분석)

- **Meziantou.Analyzer** (커뮤니티 베스트 프랙티스)

- **Roslynator** (refactoring + 분석)

- **SecurityCodeScan** (보안 취약점)

`.editorconfig`로 룰을 통제:

[*.cs]

dotnet_diagnostic.CA1822.severity = warning # mark members as static

dotnet_diagnostic.IDE0005.severity = error # unused using

dotnet_analyzer_diagnostic.category-Style.severity = suggestion

**Nullable enforcement**:

이 두 줄이 모던 .NET 프로젝트의 가장 큰 차이다. null 안전성을 컴파일러가 강제.

**NuGet 6 + Central Package Management**:

Directory.Packages.props 한 파일로 솔루션 전체의 패키지 버전 통제:

각 csproj에서는 버전 없이 `<PackageReference Include="MediatR" />`만. 버전 충돌이 사라진다.

**dotnet CLI 통합**:

2026년 표준 워크플로

dotnet new aspire-starter -n MyApp # Aspire 솔루션 생성

dotnet add package Serilog.AspNetCore # 패키지 추가 (CPM이면 Directory.Packages.props에 기록)

dotnet ef migrations add InitialCreate # EF Core 마이그레이션

dotnet aspire run # Aspire 앱 실행

dotnet test --collect:"XPlat Code Coverage" # 테스트 + 커버리지

dotnet format # 자동 포매팅

dotnet workload install android ios # MAUI 워크로드

dotnet run app.cs # 단일 파일 실행 (.NET 10)

**global.json**:

루트에 두면 솔루션이 어떤 SDK 버전을 쓸지 명시.

{

"sdk": {

"version": "10.0.100",

"rollForward": "latestFeature"

}

}

이 한 파일 덕분에 팀원마다 SDK 버전이 다를 때 생기는 미묘한 버그가 사라진다.

15장 · 한국 / 일본 — 토스, 任天堂, ソフトバンク

.NET은 한국·일본 시장에서 흔히 보이지 않는 듯하지만, 실제 enterprise / 금융 / 게임 백엔드에는 광범위하게 깔려 있다.

**한국**:

- **금융권 백엔드**: 신한은행, KB국민카드, 현대카드 등 대형 금융사의 일부 백엔드가 ASP.NET / .NET 8+ 위에 있다. 특히 카드사 / 채권 / 자산관리 시스템.

- **공공 시스템**: 행정망 일부, 국세청 시스템 일부, 우체국 일부에서 .NET이 사용된다. (보안 / 감사 관점에서 마이크로소프트와의 장기 라이선스 관계가 크다.)

- **토스 (Toss)**: 대부분 JVM / Kotlin / Node.js 스택이지만, 일부 어드민 / 사내 도구가 .NET 위에 있다는 사례 보고. 공식 컨퍼런스 발표는 드묾.

- **NCSOFT, 넥슨, 펄어비스**: 게임 클라이언트는 Unity / Unreal이지만 일부 백엔드 / 사내 도구가 .NET. Unity는 자체 .NET 런타임을 쓰지만 동일한 C# 코드베이스.

- **삼성SDS, LG CNS**: SI 프로젝트에서 .NET을 선택하는 경우가 여전히 많다.

**일본**:

- **任天堂 (Nintendo)**: 일부 사내 도구 / 백엔드에 .NET. 게임 본체는 자체 엔진이지만 어드민·매니지먼트·온라인 서비스 일부.

- **ソフトバンク (SoftBank)**: 모바일 사업부의 일부 백엔드. 통신 인프라 관리 도구에 .NET이 사용된다는 발표.

- **楽天 (Rakuten)**: 백엔드의 큰 축은 Java / Python이지만 광고 / 분석 시스템 일부가 .NET.

- **NTT データ / 富士通**: 일본 SI 대기업이 .NET 기반 정부·금융 프로젝트를 다수 운영.

- **サイボウズ (Cybozu)**: kintone의 일부 서비스, 사내 도구에 .NET 사용 보고.

- **メルカリ (Mercari)**: 대부분 Go 백엔드지만 결제·정산 일부에 .NET 사용.

요약하면: **한국·일본 모두 enterprise / 금융 / 통신 / 정부 영역에서 .NET이 사실상 표준 옵션 중 하나**다. 컨퍼런스 무대에 잘 안 보일 뿐, 매출과 시스템 규모로 보면 적지 않다.

16장 · 누가 .NET을 골라야 하나

**.NET을 골라야 할 경우**:

- **엔터프라이즈 / 금융 / 정부 도메인**. 마이크로소프트 ecosystem(SQL Server, Azure AD, Office)과의 자연스러운 통합. 장기 LTS와 감사 친화성.

- **풀스택 C# 팀**. Blazor + ASP.NET Core + MAUI로 웹/모바일/데스크탑을 단일 언어로.

- **고성능 웹 백엔드**. ASP.NET Core 10 + Minimal APIs는 Go에 근접한 throughput.

- **Windows 데스크탑 / .NET 통합 도구**. WPF, WinForms, MAUI, Avalonia 중 골라 쓸 수 있음.

- **Unity 게임 개발**. C# 단일 언어로 클라이언트·서버 통일.

- **AWS Lambda / Cloud Functions 워크로드 (NativeAOT)**. cold start 우수.

**.NET을 피해야 할 경우**:

- **PaaS / serverless heavy 환경에서 JS / Python 우선**. Vercel / Cloudflare Workers 같은 환경.

- **데이터 사이언스 / ML 우선 팀**. Python 생태계가 압도적.

- **모바일 우선 (소셜 / 컨슈머 앱)**. SwiftUI / Compose / React Native / Flutter가 더 자연스러움.

- **JVM 라이브러리 자산이 많은 조직**. Kafka, Spark, Hadoop, Flink 등이 1순위라면 JVM이 자연스러움.

- **극단적 시스템 프로그래밍**. Rust / C++ / Go가 더 잘 맞음.

**의사결정 트리 (단순화)**:

Q1. 도메인은?

├── 엔터프라이즈 / 금융 / 정부 / 보험 / Windows 통합

│ └── .NET 10 + ASP.NET Core 10 + EF Core 10

├── 공개 컨슈머 웹 / SEO 중심

│ └── Next.js / Remix / SvelteKit 우선 검토

├── 게임 (Unity)

│ └── C# (.NET 호환 런타임)

└── 모바일 앱 (컨슈머)

└── Native 또는 Flutter / RN 우선

Q2. 팀 언어는?

├── C# 강함 → .NET

├── Java/Kotlin 강함 → Spring / Quarkus

├── TS/JS 강함 → Node / Deno

└── Python 강함 → FastAPI / Django

Q3. 배포 환경은?

├── Azure / On-prem Windows → .NET 자연스러움

├── AWS / GCP / K8s → .NET 가능, 단 OpenTelemetry · Aspire 활용

└── Vercel / Cloudflare / Edge → .NET 안 맞음

**한 줄 권고 (2026년 5월 기준)**:

- 엔터프라이즈 / 금융 / 통신 / 정부 신규 시스템: **.NET 10 LTS + ASP.NET Core 10 + EF Core 10 + Aspire**.

- 사내 도구 / 어드민 풀스택: **Blazor United**.

- 모바일이 .NET 팀의 추가 부담: **MAUI + Blazor Hybrid**.

- 진정한 크로스 플랫폼 데스크탑: **Avalonia 11**.

- 작은 API: **Minimal APIs**. 50개 이상 엔드포인트: **FastEndpoints**.

- CQRS는 **Wolverine**, 메시징은 **MassTransit**.

- 단일 실행 파일 / cold start 우선: **NativeAOT**.

가장 중요한 메타-권고: **.NET을 안 쓰는 게 합리적인 도메인도 분명히 있다.** 하지만 자기가 그 도메인에 있다고 단정하기 전에, 한 번쯤은 모던 .NET이 어디까지 왔는지 직접 측정해볼 가치가 있다. 2026년의 .NET은 2018년의 .NET과 거의 다른 도구다.

참고 / References

- .NET 공식 — https://dotnet.microsoft.com/

- .NET 10 발표 — https://devblogs.microsoft.com/dotnet/announcing-dotnet-10/

- .NET 9 발표 — https://devblogs.microsoft.com/dotnet/announcing-dotnet-9/

- .NET 릴리스 정책 (LTS / STS) — https://dotnet.microsoft.com/platform/support/policy/dotnet-core

- C# 13 새 기능 — https://learn.microsoft.com/dotnet/csharp/whats-new/csharp-13

- C# 14 새 기능 — https://learn.microsoft.com/dotnet/csharp/whats-new/csharp-14

- ASP.NET Core 10 — https://learn.microsoft.com/aspnet/core/release-notes/aspnetcore-10.0

- .NET Aspire — https://learn.microsoft.com/dotnet/aspire/

- Aspire GA 발표 — https://devblogs.microsoft.com/dotnet/dotnet-aspire-general-availability/

- Blazor — https://dotnet.microsoft.com/apps/aspnet/web-apps/blazor

- .NET MAUI — https://dotnet.microsoft.com/apps/maui

- Avalonia UI — https://avaloniaui.net/

- Entity Framework Core — https://learn.microsoft.com/ef/core/

- EF Core 9 발표 — https://devblogs.microsoft.com/dotnet/announcing-ef9/

- MediatR — https://github.com/jbogard/MediatR

- MediatR 상용화 발표 — https://www.jimmybogard.com/automapper-and-mediatr-going-commercial/

- MassTransit — https://masstransit.io/

- NServiceBus — https://particular.net/nservicebus

- Wolverine — https://wolverinefx.net/

- FastEndpoints — https://fast-endpoints.com/

- Carter — https://github.com/CarterCommunity/Carter

- Minimal APIs 개요 — https://learn.microsoft.com/aspnet/core/fundamentals/minimal-apis/overview

- NativeAOT 가이드 — https://learn.microsoft.com/dotnet/core/deploying/native-aot/

- Roslyn analyzers — https://learn.microsoft.com/dotnet/fundamentals/code-analysis/overview

- NuGet Central Package Management — https://learn.microsoft.com/nuget/consume-packages/central-package-management

- dotnet CLI — https://learn.microsoft.com/dotnet/core/tools/

- Marten (Postgres + Event Sourcing) — https://martendb.io/

- Dapper — https://github.com/DapperLib/Dapper

- TechEmpower Web Framework Benchmarks — https://www.techempower.com/benchmarks/

- Cybozu Tech Blog — https://blog.cybozu.io/

- Mercari Engineering — https://engineering.mercari.com/

현재 단락 (1/531)

2026년 5월. 어떤 시니어 엔지니어가 농담처럼 말했다. ".NET을 안 쓴다고 말하는 사람은 많지만, 자기 카드사 백엔드가 .NET 위에서 돌고 있다는 걸 모르는 사람도 많죠....

작성 글자: 0원문 글자: 21,218작성 단락: 0/531