Skip to content
Published on

モダン .NET 2026 — .NET 9 / .NET 10 LTS / Aspire / Blazor United / MAUI / Avalonia 11 / FastEndpoints 詳細ガイド

Authors

プロローグ — 「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 を単一の C# コードで。
  • 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# 14F# 9、VB は stable 維持
Web バックエンドASP.NET Core 10 + Minimal APIs+ FastEndpoints / Carter
データEF Core 9 / Dapper / Marten選択肢が広い
メッセージングMassTransit / NServiceBus / WolverineMediatR 商用化の影響大
CQRSWolverine / Brighter / 自前MediatR 8.x は paid
クラウドオーケストレーション.NET AspireBicep + OTel 内蔵
Web UIBlazor UnitedServer + WASM + SSR
モバイル / デスクトップ.NET MAUIiOS/Android/Mac/Win
クロスプラットフォーム デスクトップAvalonia 11Linux 含む
ゲームUnity (.NET 8 ベース)、Stride、MonoGameUnity は独自ランタイム
デプロイコンテナ + NativeAOTself-contained は縮小
パッケージNuGet 6 + Central Package Managementglobal.json 標準化
解析Roslyn analyzers + StyleCop + Sonarnullable enforcement

要点を一文ずつ:

  • ランタイムの議論は .NET 10 LTS で落ち着いた。 .NET 9 は通過する短い STS。
  • Web は Minimal APIs が default になり、FastEndpoints / Carter が「もう少し構造化された Minimal API」として定着。
  • Aspire は .NET 版の docker-compose + Kubernetes + OpenTelemetry 統合になった。
  • UI は三つに分かれた。 Web は 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 に。メモリフットプリントの小さいサービスで 30-40% 削減。
  • JIT: PGO (Profile-Guided Optimization) on by default。devirtualization と inlining がより積極的に。
  • NativeAOT の成熟: より多くのフレームワークライブラリが 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 フォーク群 — ほぼすべての主要ライブラリが .NET 10 を first-class target としている。

アップグレードの目安:

  • .NET 6 (LTS、2024-11 EOL): 即時 .NET 10 へ。
  • .NET 8 (LTS、2026-11 EOL): EF Core、MediatR などの互換性確認のうえ徐々に .NET 10 へ。
  • .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 — 9 で alpha、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 へ移動する必要がある。.NET 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 collectionsparams Span<int>params IEnumerable<int> などコレクション型に params 可能。「params int[] のみ」ではない。
  • lock 用専用型System.Threading.Lock が入り、lock(myLock) に適したモナディックな使い方。一般 object を lock に使うパターンはアナライザが警告。
  • 新しい escape sequence \e — ANSI escape (ESC 0x1B)。ターミナル ANSI カラーコードがきれいに書ける。
  • partial properties — partial method に続いて partial property も可能。source generator フレンドリー。
  • field キーワードのプレビュー — getter/setter 内で backing field に field で直接アクセス。

C# 14 の核:

  • field キーワードの正式化 — getter/setter 内で field が自動的な backing field を提供。明示的な backing field 宣言が消える。
  • partial members 拡大 — コンストラクタ、演算子、インデクサまで partial 可能。
  • null-conditional assignmentobj?.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 backing field のネーミング論争はいらない。


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

ASP.NET Core 10 は .NET 10 と同時に登場した。2026年5月時点で、モダン .NET Web の基本形は次のとおり。

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 — エンドポイントのディスパッチが reflection ではなくコンパイル時コード生成。
  • OpenTelemetry first-classAddOpenTelemetry() が標準パターン。

パフォーマンス数値 (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。

2026年でも ASP.NET Core は、最も速いメインストリーム Web フレームワークの一つだ。


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. 接続文字列が環境変数として自動注入。
  4. OpenTelemetry データが Aspire Dashboard に流れる。
  5. 分散トレース、ログ、メトリクスが一画面で見える。

Aspire Dashboard:

  • 分散トレース (waterfall view)。
  • 構造化ログ。
  • メトリクス (CPU、memory、request rate、latency)。
  • コンテナ / プロセス状態。
  • 環境変数インスペクタ。

クラウドデプロイ:

  • Azure Container Apps へ azd up 一行でデプロイ可能。
  • 他クラウドは Aspire マニフェスト → Kubernetes / Bicep / Terraform に変換。

docker-compose vs Aspire:

基準docker-composeAspire
定義言語YAMLC#
デバッグコンテナアタッチ.NET プロセスを直接デバッグ
テレメトリ別途インストール内蔵
クラウドデプロイ変換ツール別途内蔵 generator
.NET 以外のサービス良好良好 (Postgres、Redis、OS image など)

.NET マイクロサービスを運用するチームには Aspire が事実上 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

<h1>ダッシュボード</h1>
<StaticSummary />
<InteractiveChart />

InteractiveAuto は初回アクセス時に Server モード (SignalR) で速く立ち上がり、WASM ダウンロード完了後は WASM に切り替える。最初のインタラクション遅延を隠すパターン。

Blazor の強み:

  • フルスタック C#。JavaScript なしで SPA 可能 (または最小化)。
  • ASP.NET Core との統合。同じ認証、DI、ミドルウェアを使用。
  • SignalR が安定。双方向通信が自然。
  • WASM AOT ビルドで初回ロードサイズが徐々に縮小。

Blazor の弱点:

  • WASM 初期バンドルは今でも 1-3MB。圧縮後でも重い。
  • エコシステムは 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。
  • プラットフォーム別ハンドラがネイティブコントロールを描画。
  • Hot reload 対応。

MAUI Hybrid + Blazor Hybrid:

MAUI の中に BlazorWebView を載せると、Razor コンポーネントをネイティブアプリとして再利用できる。Web 用に作った Blazor UI をモバイルアプリにもほぼそのまま。

<BlazorWebView HostPage="wwwroot/index.html">
    <BlazorWebView.RootComponents>
        <RootComponent Selector="#app" ComponentType="{x:Type local:Main}" />
    </BlazorWebView.RootComponents>
</BlazorWebView>

このパターンは フルスタック .NET チームがモバイルアプリまで持つ ときに魅力的だ。React Native よりビルド/デプロイパイプラインが単純で、Flutter より .NET バックエンドとの統合が自然。

MAUI の弱点:

  • iOS / Android ネイティブ SDK の進化を100%は追従できない。
  • Linux デスクトップは公式サポートなし (コミュニティ GTK バックエンドあり)。
  • 複雑なアニメーション / 性能 critical 部分は依然ネイティブが優位。

2026年の推奨: 社内モバイル / Windows デスクトップ限定。公開アプリストア向けコンシューマアプリは 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 MAUIAvalonia 11
ガバナンスMicrosoftコミュニティ + 商用 (AvaloniaUI 社)
プラットフォームiOS/Android/Mac/WiniOS/Android/Mac/Win/Linux/WebAssembly
レンダリングプラットフォームネイティブコントロール独自レンダラ (Skia ベース)
UI 一貫性プラットフォームごと全プラットフォーム同一
デザインパターンXAML + handlersXAML + 独自コントロールツリー
Hot reload対応対応
デスクトップ重視度弱い強い

Avalonia が光るケース:

  • Linux デスクトップが本当に必要なチーム。(MAUI は不可。)
  • 全プラットフォームでピクセル単位に同じ UI が必要なケース。
  • デスクトップ中心アプリ (IDE、グラフィックスツール、音声/映像ソフト)。

実例:

  • JetBrains Rider が一部 UI で Avalonia を試行 (全面採用ではない)。
  • WasabiWallet、Camelot、AvaloniaEdit など OSS .NET デスクトップツール。
  • 多くの enterprise 社内ツール が WPF から Avalonia へ移行中。WPF が Windows 専用のため、Mac/Linux クライアントのために。

弱点:

  • モバイルは可能だがネイティブ感が不足。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 をより軽量に。値オブジェクトのモデリングが自然。
  • Primitive collectionsList<int> をカラムにそのままマッピング。
  • Bulk operationsExecuteUpdateAsyncExecuteDeleteAsync で 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");
        });
    }
}

// 一括削除 - SQL 一発
await db.Orders
    .Where(o => o.Status == OrderStatus.Cancelled && o.CreatedAt < DateTime.UtcNow.AddYears(-1))
    .ExecuteDeleteAsync();

EF Core vs Dapper vs Marten:

ツールモデル強み弱み
EF CoreORM / change tracking豊かな LINQ、マイグレーション、関係複雑クエリは SQL 可読性が落ちる
DapperMicro-ORM速い、SQL を手書きすべて手動
MartenPostgres + Event Sourcingdocument DB + event storePostgres 専用
LinqToDBSQL-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商用安定。費用発生。
Wolverinein-process + messagingOSS (MIT)Jeremy D. Miller。CQRS + saga 統合。
Brightercommand processorOSS (BSD)メッセージング統合。
自前実装DI + interfacen/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):

ツールトランスポートライセンス強み
MassTransitRabbitMQ、Azure Service Bus、Kafka などOSS (Apache) → 一部 Pro最も広く使われる
NServiceBus多様商用エンタープライズ。saga が強い。
WolverineRabbitMQ、Kafka、Azure Service BusOSS (MIT)CQRS とメッセージング統合
RebusRabbitMQ、Azure Service Bus など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 APIControllersFastEndpointsCarter
ボイラープレート極小多い少ない極小
整理弱い強い強い (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 コンパイルで単一のネイティブ実行ファイルを生成する こと。

長所:

  • 起動時間: 通常 50-100ms (vs JIT の 200-500ms)。cold start に敏感なワークロード (serverless、CLI ツール) に好適。
  • メモリ: 30-40% 小さい。JIT 関連メタデータがない。
  • 単一実行ファイル: 10-30MB の stand-alone バイナリ。CoreCLR / framework を別途同梱しない。
  • trim 済みバイナリ: 未使用コード削除。

制約:

  • Reflection 制限: 伝統的に reflection を多用するライブラリは動かない。Serializer、ORM、IoC コンテナはすべて source generator を使う必要がある。
  • 動的コード生成不可: Reflection.Emit が動かない。
  • JIT コンパイルなし: ランタイムに新しいアセンブリをロードできない。

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:

<PropertyGroup>
    <PublishAot>true</PublishAot>
    <InvariantGlobalization>true</InvariantGlobalization>
</PropertyGroup>
dotnet publish -c Release -r linux-x64
# 単一ネイティブ実行ファイル → bin/Release/net10.0/linux-x64/publish/MyApi
# サイズ: 通常 15-25 MB

使うとき:

  • AWS Lambda、Cloud Functions などの serverless。
  • CLI ツール (dotnet-tool の代替)。
  • コンテナの cold start に敏感なマイクロサービス。
  • 起動時間がビジネス的に重要なすべての場所。

使わないとき:

  • Reflection 依存ライブラリが多いレガシー。
  • ビルド時間 / デバッグの容易さが優先される開発フェーズ。
  • レガシー EF Core / 複雑な IoC コンテナを持つモノリス。

14章 · Roslyn analyzers / NuGet / dotnet CLI

Roslyn analyzers:

.NET アナライザはコンパイル時にコード品質・セキュリティ・性能の問題を捕まえる。2026年にはほぼ default で以下を入れる:

  • .NET 組み込みアナライザ (CA、IDE ルール)。
  • StyleCop.Analyzers (コードスタイル)。
  • SonarAnalyzer.CSharp (静的解析)。
  • Meziantou.Analyzer (コミュニティのベストプラクティス)。
  • Roslynator (リファクタリング + 解析)。
  • 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:

<Nullable>enable</Nullable>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>

この二行がモダン .NET プロジェクトとレガシーの最大の差だ。null 安全性をコンパイラが強制。

NuGet 6 + Central Package Management:

Directory.Packages.props 一つのファイルでソリューション全体のパッケージバージョンを制御:

<Project>
  <PropertyGroup>
    <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
  </PropertyGroup>
  <ItemGroup>
    <PackageVersion Include="MediatR" Version="8.4.0" />
    <PackageVersion Include="EntityFrameworkCore.Sqlite" Version="10.0.0" />
    <PackageVersion Include="Serilog.AspNetCore" Version="8.0.3" />
  </ItemGroup>
</Project>

各 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 workload
dotnet run app.cs                         # 単一ファイル実行 (.NET 10)

global.json:

ルートに置くとソリューションが使う SDK バージョンを明示できる。

{
  "sdk": {
    "version": "10.0.100",
    "rollForward": "latestFeature"
  }
}

この一ファイルのおかげで、チームメンバごとに SDK バージョンが違うときに起きる微妙なバグが消える。


15章 · 日本 / 韓国 — 任天堂、ソフトバンク、トス

.NET は日本や韓国のテックメディアではあまり目立たないが、実際の enterprise / 金融 / ゲームバックエンドには広く敷かれている。

日本:

  • 任天堂 (Nintendo): 一部の社内ツール / バックエンドに .NET。ゲーム本体は独自エンジンだが、管理・マネジメント・オンラインサービスの一部で使用。
  • ソフトバンク (SoftBank): モバイル事業部の一部バックエンド。通信インフラ管理ツールに .NET を使うという発表あり。
  • 楽天 (Rakuten): バックエンドの中心は Java / Python だが、広告 / 分析システムの一部が .NET。
  • NTT データ / 富士通: 日本の SI 大手が .NET ベースの政府・金融プロジェクトを多数運営。
  • サイボウズ (Cybozu): kintone の一部サービス、社内ツールで .NET 使用報告あり。
  • メルカリ (Mercari): 大半が Go バックエンドだが、決済・精算の一部に .NET。

韓国:

  • 金融バックエンド: 新韓銀行、KB 国民カード、現代カードなど大型金融機関のバックエンドの一部が ASP.NET / .NET 8+ の上にある。特にカード / 債権 / 資産管理システム。
  • 公共システム: 行政網の一部、国税庁システムの一部、郵便局の一部で .NET が使われる。(セキュリティ / 監査の観点で Microsoft との長期ライセンス関係が大きい。)
  • トス (Toss): 大半は JVM / Kotlin / Node.js スタックだが、一部の管理画面 / 社内ツールが .NET の上にあるという報告。公式カンファレンス発表は稀。
  • NCSOFT、Nexon、Pearl Abyss: ゲームクライアントは Unity / Unreal だが、一部バックエンド / 社内ツールが .NET。Unity は独自の .NET ランタイムだが同じ C# コードベース。
  • Samsung SDS、LG CNS: SI プロジェクトで .NET を選ぶケースが今でも多い。

まとめると: 日本も韓国も、enterprise / 金融 / 通信 / 政府ドメインで .NET は事実上の標準選択肢の一つ。カンファレンスのステージには出にくいが、売上とシステム規模で見ると軽くない。


16章 · 誰が .NET を選ぶべきか

.NET を選ぶべきケース:

  • エンタープライズ / 金融 / 政府ドメイン。Microsoft エコシステム (SQL Server、Azure AD、Office) との自然な統合。長寿命 LTS と監査適性。
  • フルスタック C# チーム。Blazor + ASP.NET Core + MAUI で Web/モバイル/デスクトップを単一言語に。
  • 高性能 Web バックエンド。ASP.NET Core 10 + Minimal APIs は Go に迫るスループット。
  • Windows デスクトップ / .NET 統合ツール。WPF、WinForms、MAUI、Avalonia から選択可能。
  • Unity ゲーム開発。C# 単一言語でクライアント・サーバを統一。
  • AWS Lambda / Cloud Functions ワークロード (NativeAOT)。cold start に優れる。

.NET を避けるべきケース:

  • PaaS / serverless 中心で JS / Python 優先の環境。Vercel / Cloudflare Workers など。
  • データサイエンス / ML 優先チーム。Python エコシステムが圧倒的。
  • モバイル優先 (ソーシャル / コンシューマアプリ)。SwiftUI / Compose / React Native / Flutter のほうが自然。
  • JVM ライブラリ資産が多い組織。Kafka、Spark、Hadoop、Flink が一級なら JVM が自然。
  • 極端なシステムプログラミング。Rust / C++ / Go の方が合う。

意思決定ツリー (簡略化):

Q1. ドメインは?
├── エンタープライズ / 金融 / 政府 / 保険 / Windows 統合
│   └── .NET 10 + ASP.NET Core 10 + EF Core 10
├── 公開コンシューマ Web / 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 / オンプレ 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