필사 모드: Modern .NET 2026 — .NET 9 / .NET 10 LTS / Aspire / Blazor United / MAUI / Avalonia 11 / FastEndpoints Deep Dive
EnglishPrologue — "Another enterprise that isn't Java"
May 2026. A senior engineer at a Korean fintech said, half joking: "Lots of people say they don't use .NET. They just don't know their card issuer's backend runs on it." It's a joke, but it carries about 50% truth.
Conference stages still belong to TypeScript, Go, and Rust. But payments, banking, manufacturing, government, and a meaningful slice of game backends run on .NET. And .NET itself has been busy reshaping since the .NET 5 unification in 2020, shipping a fresh major every November.
What happened between 2024 and 2026:
- **.NET 9 (Nov 2024)** — STS (Standard Term Support, 18 months). Focused on perf + CLR.
- **.NET 10 (Nov 2025, LTS)** — Long Term Support 3 years. The new default.
- **ASP.NET Core 10** — Minimal API matures, OpenAPI built in.
- **Aspire (Nov 2024 GA)** — Cloud-native orchestration + telemetry.
- **Blazor United** — Server / WASM / SSR / streaming as one model.
- **.NET MAUI** — Stabilized. Single C# for iOS/Android/Mac/Win.
- **Avalonia 11** — Truly cross-platform desktop, Linux included.
- **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.
This post lays out **a map of .NET in 2026** in one read. Which version do you pick. ASP.NET Core 10 vs FastEndpoints. Do you really need Aspire. MAUI vs Avalonia 11. EF Core vs Dapper. CQRS patterns after MediatR went commercial. The real limits of NativeAOT. And who should pick .NET in the first place.
One thing up front: **.NET is not dead.** Far from it — in Korean and Japanese enterprise / finance / government systems it is, quietly, more entrenched than ever. It's a tool with a different grain from JVM / Go / Node, and there are domains where that grain fits perfectly.
1. The 2026 .NET map — in one table
| Area | De facto standard in 2026 | Note |
| --- | --- | --- |
| Runtime | **.NET 10 LTS** (2025-11) | .NET 9 EOL imminent (2026-05) |
| Language | C# 13 / C# 14 | F# 9, VB stable maintained |
| Web backend | ASP.NET Core 10 + Minimal APIs | + FastEndpoints / Carter |
| Data | EF Core 9 / Dapper / Marten | Wide choice |
| Messaging | MassTransit / NServiceBus / Wolverine | MediatR going paid changed things |
| CQRS | Wolverine / Brighter / hand-rolled | MediatR 8.x is paid |
| Cloud orchestration | **.NET Aspire** | Bicep + OTel built in |
| Web UI | **Blazor United** | Server + WASM + SSR |
| Mobile / desktop | .NET MAUI | iOS/Android/Mac/Win |
| Cross-platform desktop | **Avalonia 11** | Linux included |
| Game | Unity (.NET 8 based), Stride, MonoGame | Unity has its own runtime |
| Deployment | Container + NativeAOT | self-contained shrinking |
| Packages | NuGet 6 + Central Package Management | global.json standardized |
| Analysis | Roslyn analyzers + StyleCop + Sonar | nullable enforcement |
The headline summary:
- **The runtime conversation is settled — .NET 10 LTS.** .NET 9 is the short STS you pass through.
- **Web defaults to Minimal APIs**, with FastEndpoints / Carter sitting just above as "more structured Minimal API".
- **Aspire became the .NET-native docker-compose + Kubernetes + OpenTelemetry combo.**
- **UI split three ways.** Web is Blazor United, mobile/desktop is MAUI, truly cross-platform (incl. Linux) is Avalonia 11.
- **CQRS scattered after MediatR went commercial** — Wolverine / Brighter / hand-rolled.
2. .NET 10 LTS (2025-11) — The flagship release
.NET 10 went GA in November 2025 as Long Term Support, supported until November 2028. It follows .NET 6 (2021-11) and .NET 8 (2023-11) in the LTS line, with .NET 9 sitting between them as STS.
Key changes:
- **CLR / GC**: DATAS (Dynamically Adapting To Application Sizes) GC is now default. 30-40% smaller memory footprint for low-memory services.
- **JIT**: PGO (Profile-Guided Optimization) on by default. Devirtualization and inlining get more aggressive.
- **NativeAOT maturity**: More framework libraries are AOT-safe. ASP.NET Core minimal API + parts of EF Core are now AOT-capable.
- **JSON**: System.Text.Json formally supports polymorphism, snake_case naming, and IAsyncEnumerable streaming.
- **Threading**: TimeProvider, PriorityQueue improvements. Async LINQ goes stable.
- **C# 14 shipped alongside**: field accessor, partial properties/methods, null-conditional assignment.
- **NuGet 6 + Central Package Management**: One Directory.Packages.props file controls the version of every package across the solution.
- **dotnet CLI unification**: `dotnet run app.cs` (single-file run) is officially supported.
LTS doesn't just mean "longer patch window" — it means **the ecosystem is most aligned**. EF Core 10, ASP.NET Core 10, the Aspire stable channel, MassTransit, the MediatR forks — nearly every major library treats .NET 10 as a first-class target.
Upgrade guidance:
- .NET 6 (LTS, EOL 2024-11): Move to .NET 10 immediately.
- .NET 8 (LTS, EOL 2026-11): Move to .NET 10 at your own pace after a compat audit (EF Core, MediatR, etc.).
- .NET 9 (STS, EOL 2026-05): Move fast — it's about to end.
3. .NET 9 (2024-11) — STS in context
.NET 9 is STS, meaning 18 months of support, which lands in May 2026 — right around when this post is written. .NET 9 served as "the lab notebook for the next LTS, .NET 10".
Features that landed in .NET 9 and got polished in .NET 10:
- **DATAS GC** — opt-in in .NET 9, default in .NET 10.
- **System.Text.Json polymorphism** — alpha in 9, stable in 10.
- **Built-in OpenAPI** — .NET 9 dropped the Swashbuckle dependency in favor of `Microsoft.AspNetCore.OpenApi`; .NET 10 integrated the UI.
- **Kestrel HTTP/3** — production-ready in .NET 9.
- **NativeAOT expansion** — more libraries supported in .NET 9.
Bottom line: **teams on .NET 9 must move to .NET 10 by mid-2026**. Going back to 8 (LTS) is pointless — .NET 8 itself ends in November 2026.
The LTS / STS rhythm is clear now:
- **LTS** — even majors (8, 10, 12...), 3-year support, enterprise default.
- **STS** — odd majors (7, 9, 11...), 18 months, faster experiment cycle.
Enterprises typically skip STS releases entirely. The canonical path is .NET 6 → 8 → 10.
4. C# 13 / C# 14 — params collections, field accessor
C# ships a new major every November alongside .NET. C# 13 (2024) and C# 14 (2025) landed with .NET 9 and .NET 10 respectively.
**C# 13 highlights**:
- **params collections** — `params Span<int>`, `params IEnumerable<int>` and other collection types. No more "params int[] only".
- **dedicated lock type** — `System.Threading.Lock` arrives, with monadic-style usage from `lock(myLock)`. Using plain object as a lock now gets flagged by analyzers.
- **new escape sequence `\e`** — ANSI escape (ESC 0x1B). Terminal color codes look cleaner.
- **partial properties** — joining partial methods. Source-generator friendly.
- **preview `field` keyword** — direct backing-field access via `field` inside a getter/setter.
**C# 14 highlights**:
- **`field` keyword officially** — `field` provides an automatic backing field inside getters/setters. No more explicit backing-field declarations.
- **partial members expanded** — constructors, operators, indexers can be partial.
- **null-conditional assignment** — `obj?.Prop = value` skips the assignment when obj is null.
- **extended nameof** — works on unbound type arguments too.
- **extension members evolved** — extension properties in preview, alongside extension methods.
The `field` keyword in one shot:
// Old style — explicit backing field
private string _name = string.Empty;
public string Name
{
get => _name;
set => _name = value?.Trim() ?? throw new ArgumentNullException();
}
// C# 14 — field keyword
public string Name
{
get;
set => field = value?.Trim() ?? throw new ArgumentNullException();
} = string.Empty;
You don't hand-declare `_name`; the compiler generates it. The `_camelCase` backing-field naming debate goes away.
5. ASP.NET Core 10 — performance + DX
ASP.NET Core 10 shipped with .NET 10. As of May 2026, the canonical shape of a modern .NET web app:
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 integration
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();
**What's different**:
- **OpenAPI built in** — Swashbuckle no longer required. `Microsoft.AspNetCore.OpenApi` is the default.
- **Scalar UI integration** — A lighter, cleaner OpenAPI viewer than Swagger UI.
- **JSON streaming** — IAsyncEnumerable naturally flows as chunked transfer encoding.
- **HTTP/3 default** — Kestrel ships production-ready HTTP/3.
- **Compiled routing** — Endpoint dispatch generated at compile time, not via reflection.
- **OpenTelemetry first-class** — `AddOpenTelemetry()` is the standard pattern.
**Performance numbers** (TechEmpower-style microbench):
- ASP.NET Core 10 Minimal API + Kestrel: 700k+ req/s (Plaintext).
- ASP.NET Core 10 + EF Core 9 + Postgres: 80-100k req/s (Fortunes).
- Comparable Go (net/http): 600k req/s.
- Comparable Node (Fastify): 200k req/s.
In 2026 ASP.NET Core remains one of the fastest mainstream web frameworks.
6. Aspire (Nov 2024 GA) — Cloud-native orchestration
Aspire went GA in November 2024 — .NET's cloud-native orchestration + local dev environment + telemetry integration toolkit. The name is grand, but the essence is simple.
**What Aspire solves**:
- Define dependencies in .NET code instead of `docker-compose up`.
- One solution that boots several microservices + Postgres + Redis + RabbitMQ.
- OpenTelemetry auto-injected + dashboard built in.
- For cloud deploy, automatic Bicep / Terraform / Kubernetes manifest generation.
**The AppHost project**:
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` on this code:
1. Postgres / Redis / RabbitMQ containers spin up automatically.
2. API service and Web Frontend start as .NET processes.
3. Connection strings are injected as environment variables.
4. OpenTelemetry data flows into the Aspire Dashboard.
5. Distributed traces, logs, metrics — all on one screen.
**Aspire Dashboard**:
- Distributed trace (waterfall view).
- Structured logs.
- Metrics (CPU, memory, request rate, latency).
- Container / process status.
- Environment-variable inspector.
**Cloud deploy**:
- `azd up` deploys to Azure Container Apps in one command.
- Other clouds: Aspire manifest converts to Kubernetes / Bicep / Terraform.
**Docker compose vs Aspire**:
| Criterion | docker-compose | Aspire |
| --- | --- | --- |
| Definition language | YAML | C# |
| Debugging | Attach to container | Direct .NET process debugging |
| Telemetry | Separate install | Built in |
| Cloud deploy | Separate conversion | Built-in generator |
| Non-.NET services | Works well | Works well (Postgres, Redis, OS images, etc.) |
For teams running .NET microservices, Aspire became the de facto default. In polyglot environments with many non-.NET services, docker-compose still feels natural.
7. Blazor United — Server + WASM + SSR + streaming
Eight years after the 2018 WebAssembly hype, in 2026 Blazor settled into a single model where one component can pick from several render modes. Microsoft's docs call this Blazor United.
**Four render modes**:
1. **Static SSR** — Server renders once. Fastest, no interactivity.
2. **Streaming SSR** — Streams async data results via chunked transfer.
3. **Server interactive** — SignalR-based, event handling on the server.
4. **WebAssembly interactive** — Client WASM, offline-capable.
A single page can mix modes per component.
@page "/dashboard"
@rendermode InteractiveAuto
`InteractiveAuto` boots fast in Server mode (SignalR) on first visit, then flips to WASM after the WASM payload finishes downloading. A pattern that hides the first-interaction latency.
**Blazor strengths**:
- Full-stack C#. SPA without JavaScript (or with it minimized).
- Integrates with ASP.NET Core — same auth, DI, middleware.
- SignalR is stable. Bi-directional communication feels natural.
- WASM AOT builds steadily shrinking initial payload.
**Blazor weaknesses**:
- Initial WASM bundle still 1-3MB. Heavy even after compression.
- Smaller ecosystem than React / Vue.
- WASM performance on mobile browsers still trails desktop.
- Designer / component marketplace is thin.
**Who uses it**: Internal tools, B2B admin, full-stack .NET teams' SPAs. Public marketing or SEO-critical pages stay on Static SSR.
8. .NET MAUI — Cross-platform native
.NET MAUI (Multi-platform App UI) succeeded Xamarin.Forms in 2022 and stabilized between 2024 and 2026. iOS / Android / macOS / Windows from a single C# codebase.
**MAUI structure**:
- Single project, single codebase.
- XAML or C# markup for UI.
- Per-platform handlers render native controls.
- Hot reload supported.
**MAUI Hybrid + Blazor Hybrid**:
A BlazorWebView inside MAUI lets you reuse Razor components as a native app. Blazor UI built for the web ends up nearly as-is in the mobile app.
This pattern is attractive when **a full-stack .NET team also needs a mobile app**. Build/deploy is simpler than React Native, and integration with the .NET backend is more natural than Flutter.
**MAUI weaknesses**:
- Doesn't 100% track iOS / Android native SDK evolution.
- Linux desktop isn't officially supported (community GTK backend exists).
- Complex animations / perf-critical surfaces still favor native.
**2026 recommendation**: Internal mobile / Windows desktop. For public app-store consumer apps, compare with Flutter, SwiftUI/Compose, React Native first.
9. Avalonia 11 — A truly cross-platform UI
Avalonia is the community-maintained, .NET Foundation-operated open-source cross-platform UI framework. 11.0 shipped in November 2023, with 11.1 / 11.2 / 11.3 following through 2024-2025.
**vs MAUI**:
| Criterion | .NET MAUI | Avalonia 11 |
| --- | --- | --- |
| Governance | Microsoft | Community + commercial (AvaloniaUI company) |
| Platforms | iOS/Android/Mac/Win | iOS/Android/Mac/Win/**Linux**/WebAssembly |
| Rendering | Native controls per platform | Own renderer (Skia-based) |
| UI consistency | Differs per platform | Identical on every platform |
| Design pattern | XAML + handlers | XAML + own control tree |
| Hot reload | Supported | Supported |
| Desktop focus | Weak | Strong |
**When Avalonia shines**:
- **Teams that genuinely need Linux desktop**. (MAUI can't.)
- **Pixel-identical UI across all platforms**.
- **Desktop-centric apps** (IDEs, graphics tools, audio/video software).
**Real-world examples**:
- **JetBrains Rider** experimented with Avalonia for some UI (not a full adoption).
- **WasabiWallet, Camelot, AvaloniaEdit** and other open-source .NET desktop tools.
- **Many enterprise internal tools** migrating from WPF to Avalonia — WPF is Windows-only, so reaching Mac/Linux clients drives the move.
**Weaknesses**:
- Mobile works but doesn't feel as native. Concede that lane to MAUI.
- Smaller community control marketplace than WPF.
**2026 recommendation**: WPF's natural successor. First pick for cross-platform desktop .NET apps that include Linux/Mac.
10. Entity Framework Core 9
EF Core 9 shipped with .NET 9 in November 2024, and EF Core 10 with .NET 10 in November 2025. As of May 2026 the de facto standard is EF Core 10.
**Changes over the last 2-3 years**:
- **JSON columns officially supported** — Postgres `jsonb`, SQL Server JSON, SQLite JSON. LINQ queries reach inside JSON.
- **Complex types** — Owned types but lighter. Modeling value objects feels natural.
- **Primitive collections** — Map a `List<int>` directly to a column.
- **Bulk operations** — `ExecuteUpdateAsync`, `ExecuteDeleteAsync` for N+1-free batch updates.
- **Query splitting default** — Prevents JOIN explosion.
**Typical code**:
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 - one SQL statement
await db.Orders
.Where(o => o.Status == OrderStatus.Cancelled && o.CreatedAt < DateTime.UtcNow.AddYears(-1))
.ExecuteDeleteAsync();
**EF Core vs Dapper vs Marten**:
| Tool | Model | Strengths | Weaknesses |
| --- | --- | --- | --- |
| **EF Core** | ORM / change tracking | Rich LINQ, migrations, relationships | Complex queries hurt SQL readability |
| **Dapper** | Micro-ORM | Fast, SQL hand-written | Everything manual |
| **Marten** | Postgres + event sourcing | Document DB + event store | Postgres only |
| **LinqToDB** | SQL-shape LINQ | Performance + LINQ expressiveness | Learning curve |
The 2026 default is **EF Core + Dapper mixed**. EF Core for CRUD and domain mutations, Dapper for heavy report / analytics queries.
11. MediatR / MassTransit / NServiceBus — CQRS and messaging
In late 2024 the .NET CQRS scene shook: **MediatR moved to a commercial license from 8.x**. The same author's AutoMapper introduced a paid edition around the same time. The decision sparked sharp community debate.
**Current options**:
| Tool | Model | License | Note |
| --- | --- | --- | --- |
| **MediatR 8+** | In-process mediator | Commercial | Stable. Costs money. |
| **Wolverine** | In-process + messaging | OSS (MIT) | Jeremy D. Miller. CQRS + saga integrated. |
| **Brighter** | Command processor | OSS (BSD) | Messaging-integrated. |
| **Hand-rolled** | DI + interface | n/a | Small projects do fine. |
**Wolverine example**:
// Handler — discovered by method signature, no interface needed
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);
}
}
// Call site
var result = await bus.InvokeAsync<OrderCreated>(new CreateOrder(...));
Method-signature discovery without interfaces is the Wolverine signature. MediatR's `IRequestHandler` boilerplate evaporates.
**Messaging (out-of-process)**:
| Tool | Transports | License | Strengths |
| --- | --- | --- | --- |
| **MassTransit** | RabbitMQ, Azure Service Bus, Kafka, etc. | OSS (Apache) + some Pro | Most widely used |
| **NServiceBus** | Various | Commercial | Enterprise. Strong saga story. |
| **Wolverine** | RabbitMQ, Kafka, Azure Service Bus | OSS (MIT) | CQRS + messaging integrated |
| **Rebus** | RabbitMQ, Azure Service Bus, etc. | OSS | Lightweight |
**MassTransit saga pattern**:
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 recommendations**:
- **Simple in-process mediator**: Hand-roll or Wolverine.
- **CQRS + messaging together**: Wolverine.
- **Enterprise + commercial support**: NServiceBus.
- **Already on MediatR + MassTransit**: Cost out MediatR 8+ and decide whether to switch.
12. FastEndpoints / Carter / Minimal APIs
ASP.NET Core 10 routing has three flavors now.
**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);
});
Pros: lightweight, fast startup. Cons: Program.cs balloons in a large API.
**2. Controllers (classic)**:
[ApiController]
[Route("orders")]
public class OrdersController : ControllerBase
{
[HttpGet("{id:guid}")]
public async Task<IActionResult> Get(Guid id) { ... }
}
Pros: familiar, class-level organization. Cons: lots of boilerplate.
**3. FastEndpoints / Carter (structured minimal)**:
FastEndpoints forces the "endpoint per class" pattern.
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** is the spiritual successor to Nancy with module-level routing.
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);
});
}
}
**Comparison**:
| Criterion | Minimal API | Controllers | FastEndpoints | Carter |
| --- | --- | --- | --- | --- |
| Boilerplate | Very low | High | Low | Very low |
| Organization | Weak | Strong | Strong (per-class) | Medium (per-module) |
| Performance | Fastest | Slightly slower | Fastest (on Minimal) | Fastest (on Minimal) |
| OpenAPI | Auto | Auto | Auto + rich | Auto |
| Learning curve | Low | Low | Medium | Low |
| Large-API friendly | Weak | Strong | Strong | Medium |
**Recommendation**: Below 50 endpoints, Minimal API. Above that, FastEndpoints or Controllers. Carter if you want lightweight module splits.
13. NativeAOT — Small single-file executables
NativeAOT went GA in .NET 7 and matured through .NET 9 and 10. The core idea: **ahead-of-time compile to a single native executable instead of relying on the JIT**.
**Strengths**:
- **Startup time**: Typically 50-100ms (vs JIT's 200-500ms). Good for cold-start-sensitive workloads (serverless, CLI tools).
- **Memory**: 30-40% smaller. No JIT metadata.
- **Single executable**: 10-30MB stand-alone binary. No CoreCLR / framework bundled separately.
- **Trimmed binary**: Dead code removed.
**Limitations**:
- **Reflection restricted**: Reflection-heavy libraries don't work. Serializers, ORMs, IoC containers must all use source generators.
- **No dynamic code gen**: Reflection.Emit doesn't function.
- **No JIT compilation**: Loading a new assembly at runtime is impossible.
**AOT-friendly libraries**:
- System.Text.Json (with source generator).
- Minimal APIs / FastEndpoints.
- Parts of EF Core (8+ progressively).
- Dapper.
- Refit (HTTP client).
- ASP.NET Core RequestDelegateGenerator.
**AOT-unfriendly**:
- Some IoC containers (Autofac, Castle Windsor, etc.).
- Newtonsoft.Json (reflection-dependent).
- Some MediatR patterns.
- AutoMapper.
**Example — AOT minimal API**:
dotnet publish -c Release -r linux-x64
Single native executable -> bin/Release/net10.0/linux-x64/publish/MyApi
Size: typically 15-25 MB
**When to use**:
- AWS Lambda, Cloud Functions and other serverless.
- CLI tools (alternative to dotnet-tool).
- Microservices in containers with cold-start sensitivity.
- Anywhere startup time is business-critical.
**When not to use**:
- Legacy code with many reflection-dependent libraries.
- Development phase where build time / debug ergonomics matter.
- Monoliths with legacy EF Core / complex IoC containers.
14. Roslyn analyzers / NuGet / dotnet CLI
**Roslyn analyzers**:
.NET analyzers catch quality / security / performance issues at compile time. The 2026 default set:
- **Built-in .NET analyzers** (CA, IDE rules).
- **StyleCop.Analyzers** (code style).
- **SonarAnalyzer.CSharp** (static analysis).
- **Meziantou.Analyzer** (community best practices).
- **Roslynator** (refactoring + analysis).
- **SecurityCodeScan** (security vulnerabilities).
`.editorconfig` controls the rules:
[*.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**:
These two lines mark the biggest gap between a modern .NET project and a legacy one. Null safety is enforced by the compiler.
**NuGet 6 + Central Package Management**:
A single Directory.Packages.props governs every package version in the solution:
Each csproj only writes `<PackageReference Include="MediatR" />` without a version. Version conflicts dissolve.
**dotnet CLI unified**:
The 2026 baseline workflow
dotnet new aspire-starter -n MyApp # Create an Aspire solution
dotnet add package Serilog.AspNetCore # Add a package (CPM writes to Directory.Packages.props)
dotnet ef migrations add InitialCreate # EF Core migration
dotnet aspire run # Run the Aspire app
dotnet test --collect:"XPlat Code Coverage" # Tests + coverage
dotnet format # Auto-format
dotnet workload install android ios # MAUI workloads
dotnet run app.cs # Single-file run (.NET 10)
**global.json**:
Place it at the repo root to pin the SDK version per solution.
{
"sdk": {
"version": "10.0.100",
"rollForward": "latestFeature"
}
}
That one file removes a whole class of subtle bugs caused by teammates running different SDKs.
15. Korea / Japan — Toss, Nintendo, SoftBank
.NET seems invisible in Korean / Japanese tech press, but it is widely deployed in enterprise / finance / game backends.
**Korea**:
- **Financial backends**: Shinhan, KB Kookmin Card, Hyundai Card — parts of large financial backends ride ASP.NET / .NET 8+. Especially card / debt / wealth-management systems.
- **Public sector**: Parts of the government administrative network, parts of the National Tax Service, parts of Korea Post run on .NET. (Security / audit considerations and long-running Microsoft licensing relationships drive this.)
- **Toss**: Mostly JVM / Kotlin / Node.js, but reports of internal admin / tooling on .NET. Rarely surfaces at public conferences.
- **NCSOFT, Nexon, Pearl Abyss**: Game clients are Unity / Unreal, but some backends / internal tooling are .NET. Unity uses its own .NET runtime but the same C# codebase.
- **Samsung SDS, LG CNS**: SI projects still pick .NET often.
**Japan**:
- **Nintendo**: .NET in some internal tooling / backends. Game engines are proprietary, but admin / management / online services pieces use it.
- **SoftBank**: .NET in mobile-division backends. Telecom infrastructure management tools have public talks mentioning .NET.
- **Rakuten**: Java / Python dominate, but ads / analytics systems include .NET.
- **NTT Data / Fujitsu**: Japanese SI giants run many .NET-based government / financial projects.
- **Cybozu**: kintone services and internal tooling have reported .NET usage.
- **Mercari**: Largely Go backends, but payment / settlement uses some .NET.
Summary: **in both Korea and Japan, .NET is a de facto standard option in enterprise / finance / telecom / government domains**. Less visible on conference stages, but plenty present by revenue and system scale.
16. Who should pick .NET
**Pick .NET when**:
- **Enterprise / finance / government domains**. Natural integration with the Microsoft ecosystem (SQL Server, Azure AD, Office). Long-lived LTS and audit friendliness.
- **Full-stack C# teams**. Blazor + ASP.NET Core + MAUI unify web/mobile/desktop in one language.
- **High-throughput web backends**. ASP.NET Core 10 + Minimal APIs approach Go-level throughput.
- **Windows desktop / .NET-integrated tools**. Choose between WPF, WinForms, MAUI, Avalonia.
- **Unity game dev**. One C# language unifies client and server.
- **AWS Lambda / Cloud Functions workloads (NativeAOT)**. Strong cold-start.
**Avoid .NET when**:
- **PaaS / serverless-heavy environments favoring JS / Python**. Vercel / Cloudflare Workers and similar.
- **Data science / ML-first teams**. The Python ecosystem dominates.
- **Mobile-first (social / consumer apps)**. SwiftUI / Compose / React Native / Flutter feel more natural.
- **Organizations with deep JVM library investment**. Kafka, Spark, Hadoop, Flink as first-class — JVM is the natural home.
- **Extreme systems programming**. Rust / C++ / Go fit better.
**Decision tree (simplified)**:
Q1. Domain?
├── Enterprise / finance / government / insurance / Windows integration
│ └── .NET 10 + ASP.NET Core 10 + EF Core 10
├── Public consumer web / SEO-first
│ └── Consider Next.js / Remix / SvelteKit first
├── Game (Unity)
│ └── C# (.NET-compatible runtime)
└── Mobile app (consumer)
└── Native or Flutter / RN first
Q2. Team language?
├── Strong C# -> .NET
├── Strong Java/Kotlin -> Spring / Quarkus
├── Strong TS/JS -> Node / Deno
└── Strong Python -> FastAPI / Django
Q3. Deployment?
├── Azure / on-prem Windows -> .NET feels natural
├── AWS / GCP / K8s -> .NET works, lean on OpenTelemetry and Aspire
└── Vercel / Cloudflare / Edge -> .NET is a poor fit
**One-line recommendations (as of May 2026)**:
- New enterprise / finance / telecom / government systems: **.NET 10 LTS + ASP.NET Core 10 + EF Core 10 + Aspire**.
- Internal tools / admin full-stack: **Blazor United**.
- Mobile as an extra burden for the .NET team: **MAUI + Blazor Hybrid**.
- True cross-platform desktop: **Avalonia 11**.
- Small API: **Minimal APIs**. Above 50 endpoints: **FastEndpoints**.
- CQRS: **Wolverine**, messaging: **MassTransit**.
- Single executable / cold-start first: **NativeAOT**.
The most important meta-recommendation: **there are domains where not picking .NET is the rational choice**. But before you assume you're in one of them, it's worth measuring how far modern .NET has come for yourself. The .NET of 2026 is nearly a different tool from the .NET of 2018.
References
- .NET official — https://dotnet.microsoft.com/
- .NET 10 announcement — https://devblogs.microsoft.com/dotnet/announcing-dotnet-10/
- .NET 9 announcement — https://devblogs.microsoft.com/dotnet/announcing-dotnet-9/
- .NET release policy (LTS / STS) — https://dotnet.microsoft.com/platform/support/policy/dotnet-core
- C# 13 new features — https://learn.microsoft.com/dotnet/csharp/whats-new/csharp-13
- C# 14 new features — 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 announcement — 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 announcement — https://devblogs.microsoft.com/dotnet/announcing-ef9/
- MediatR — https://github.com/jbogard/MediatR
- MediatR commercial announcement — 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 overview — https://learn.microsoft.com/aspnet/core/fundamentals/minimal-apis/overview
- NativeAOT guide — 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)
May 2026. A senior engineer at a Korean fintech said, half joking: "Lots of people say they don't us...