- .NET Aspire の概要

#dotnet #Aspire

新規に .NET(C#) を利用してのサービスを開発するのであれば、.NET Aspire にしてみる。というはアリだと思います。結局のところ AppHost などは本番環境では使わない、Project.XXX のみを利用ビルド/デプロイすることになるので従来通りのワークフローとそこまで変わりはないと思います。(ローカルでの開発体験は変わってきます)

.NET Aspire とは

.NET Aspireは、観測可能でプロダクションレディのアプリを構築するためのツール、テンプレート、パッケージのセットです。.NET Aspireは、モダンアプリ開発のブートストラップや特定の課題を改善するNuGetパッケージのコレクションを通じて提供されます。今日のアプリは一般的に、データベース、メッセージング、キャッシングなどの多数のサービスを消費しており、その多くは.NET Aspire Integrationsでサポートされています。

.NET Aspire は、さまざまなプロジェクトやリソースを持つアプリケーションの構築体験を向上させます。デプロイされたシナリオをエミュレートする開発時間の生産性向上により、相互接続されたアプリを迅速に開発できます。柔軟性を考慮して設計された .NET Aspire では、好みのツールやワークフローでパーツを置き換えたり拡張したりできます。

主な機能について

機能 説明
開発時のオーケストレーション ローカル開発を簡単にするため、アプリの構成と接続を管理(例:Redisコンテナ作成)。
統合 Redis、PostgreSQLなどのサービスのための標準化されたNuGetパッケージ。
テンプレート・ツール Visual Studio、VS Code、.NET CLI用のテンプレートとツール。

開発時のオーケストレーション

.NET Aspire ではアプリの構成と相互接続の管理を簡略化して ローカル開発 体験を強化することに重きをおいています。.NET Aspire のオーケストレーションは運用環境で利用される kubernetes などを置き換えることは意図していないが重要 です。

サンプルコード

// Create a distributed application builder given the command line arguments.
var builder = DistributedApplication.CreateBuilder(args);

// Add a Redis server to the application.
var cache = builder.AddRedis("cache");

// Add the frontend project to the application and configure it to use the 
// Redis server, defined as a referenced dependency.
builder.AddProject<Projects.MyFrontend>("frontend")
       .WithReference(cache)
       .WaitFor(cache);

上記では、

  1. Redis のコンテナを作成
  2. Projects.MyFrontend は Redis のコンテナ起動を待つ
  3. Projects.MyFrontend が Redis へ接続できるように情報を持たせる

Docker Compose などで構成してたことが C# コードになりつつ YAML で構成するよりは簡略化された記述が可能になります。

Aspire 統合

Aspire 統合は2つに分類でき

ホスティング統合

AppHost プロジェクトのことを指します。
公式の言としては以下のこと行う機能のことです。

ホスティング統合では、リソース (コンテナーやクラウド リソースなど) をプロビジョニングするか、既存のインスタンス (ローカル SQL サーバーなど) をポイントすることで、アプリケーションを構成します。 これらのパッケージは、キャッシュ、データベース、ログ記録、ストレージ、メッセージング システムなど、さまざまなサービス、プラットフォーム、または機能をモデル化します。

クライアント統合

Service Defaults プロジェクトという形でいくつかのよく使う外部サービスへの接続を簡略化したパッケージ群のことを指します。

統合では、クライアント ライブラリを結び付けて依存関係挿入 (DI)を し、構成スキーマを定義し、必要に応じて、正常性チェック、回復性、および テレメトリ 追加します。 .NET .NET Aspire クライアント統合ライブラリの先頭に Aspire. が付き、統合する完全なパッケージ名 (Aspire.StackExchange.Redisなど) が含まれます。

それ以外のインテグレーションについてはこちらをみるとよいでしょう。

プロジェクトを作成すると前述の Service Defaults プロジェクトが作成されるのですが、そこには

テンプレート・ツール

Visual Studio や、Visual Studio Code, CLI 等用にプロジェクトテンプレートやツールが用意されています。
テンプレートを利用することで直ちにアプリケーションとして動く最低限の仕組みが備わったプロジェクトが作成されます。

Aspire プロジェクトの作成方法

要件など

以下公式から抜粋
.NET 8.0 または .NET 9.0

手順について

今回は CLI からプロジェクトテンプレートを利用してスターターアプリを作成します。

1. Aspire テンプレートのインストール

dotnet new install Aspire.ProjectTemplates

バージョンを指定する場合は以下のようにします。

dotnet new install Aspire.ProjectTemplates::9.1.0

インストール済みの Aspire テンプレートを確認する場合は以下コマンドを実行します。

dotnet new list aspire

These templates matched your input: 'aspire'

Template Name                    Short Name              Language  Tags
-------------------------------  ----------------------  --------  -------------------------------------------------------------------------------
.NET Aspire App Host             aspire-apphost          [C#]      Common/.NET Aspire/Cloud
.NET Aspire Empty App            aspire                  [C#]      Common/.NET Aspire/Cloud/Web/Web API/API/Service
.NET Aspire Service Defaults     aspire-servicedefaults  [C#]      Common/.NET Aspire/Cloud/Web/Web API/API/Service
.NET Aspire Starter App          aspire-starter          [C#]      Common/.NET Aspire/Blazor/Web/Web API/API/Service/Cloud/Test/MSTest/NUnit/xUnit
.NET Aspire Test Project (MS...  aspire-mstest           [C#]      Common/.NET Aspire/Cloud/Web/Web API/API/Service/Test/MSTest
.NET Aspire Test Project (NU...  aspire-nunit            [C#]      Common/.NET Aspire/Cloud/Web/Web API/API/Service/Test/NUnit
.NET Aspire Test Project (xU...  aspire-xunit            [C#]      Common/.NET Aspire/Cloud/Web/Web API/API/Service/Test/xUnit

AppHostService Defaults のみを新規作成も出来ますしテスト用のテンプレートも用意されていることがわかります。

2. スターターアプリの作成

dotnet new aspire-starter --use-redis-cache --output AspireSample

3. ローカル開発向けの自己署名証明書を信頼する

dotnet dev-certs https --trust

4. スターターアプリの起動

dotnet run --project AspireSample/AspireSample.AppHost

ここまででアプリの作成と起動までが終了です。


スターターアプリを覗いてみる

csproj としては 4 つ作成されます。

AspireSample.ApiService ... Webプロジェクトから叩かれる Web API プロジェクト 
AspireSample.AppHost ... 前述のホスティング統合部分のプロジェクト
AspireSample.ServiceDefaults ... 前述のクライアント統合部分のプロジェクト
AspireSample.Web ... Blazor の Web アプリのプロジェクト

ApiService

これは何の変哲も無い、Web API 向けにプロジェクトになっています。ソースコードは Program.cs のみに集約されています。
.NET Aspire の使った場合の変更点は以下のコードで ServiceDefaults 経由でサービスの登録をしていることくらいです。

// Add service defaults & Aspire client integrations.
builder.AddServiceDefaults();

AppHost

AppHost プロジェクトは Aspire の機能が多い部分ではあります。こちらも Program.cs のみで基本的には完結しています。短いので自分がテンプレートから作成した際のコードを記載します。

var builder = DistributedApplication.CreateBuilder(args);

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

var apiService = builder
.AddProject<Projects.AspireSample_ApiService>("apiservice");

builder.AddProject<Projects.AspireSample_Web>("webfrontend")
    .WithExternalHttpEndpoints()
    .WithReference(cache)
    .WaitFor(cache)
    .WithReference(apiService)
    .WaitFor(apiService);

builder.Build().Run();

ざっくり意味合いとしては以下になります。

なお、これら起動するアプリケーション/データソースは docker コンテナで起動します。
自身が開発するサービスや関連する外部のサービス(データソースなど)が増える場合は AppHost に適宜追加していくことになります。

Aspire Dashboard

AppHost プロジェクトには .NET Aspire Dashboard という OpenTelemetry Protocol (OTLP) 形式のデータを受信して、ログ/トレース/メトリクス 等を表示してくれる機能があります。開発中だとプロジェクトを実行に自動で立ち上がるようになっています。
また、ApiService などは OTLP 形式でテレメトリを AppHost... Aspire Dashboard に送信するようにテンプレート作成時に設定されています。
ざっと各画面の機能の紹介をします。

リソース

リソース画面では起動中のプロジェクトやコンテナなどを設定や正常性などを確認することができます。

001.gif

コンソール

アプリケーションのコンソールログを確認することができます。
002.gif

構造化

各サービスから AppHost へ送信された構造化ログを確認することができます。
003.gif

トレース

分散トレースをドリルダウンした状態で確認することができます。
スパンなども確認することができます。
004.gif

メトリクス

各種メトリクスが確認できます。
005.gif

細かい機能についての解説は こちら を参照してください。

Service Defaults

よく使いそうな?設定の呼び出しをしています。
ざっくりは以下のことが行われています。


.NET Aspire はローカルでの開発体験を良くする仕組みが備わっています。初手のプロジェクト作成も非常に簡単ですし、ダッシュボード等もついてきます。外部サービスとの統合機能も順次増えていっている(自分でも作れる)ので新規で .NET アプリを作成する場合は Aspire を利用すると効率よく開発が始められるかと思います。また、ローカル開発におけるオブザーバビリティを高める機能も提供してくれているかつ、実装の手間を簡略化してくれているので昨今の複雑なサービス運用スタイルにおいては Aspire を利用するのは一定の価値があると思います。

個人的にはダッシュボードがカスタマイズ出来たり、オンコールや既存の APM やメトリクスに対する機能が増えて本番環境でも使えるレベルのダッシュボードが提供されると、ローカルと本番環境でほぼ同様の操作/設定で動作するものが手に入るので非常に嬉しいです(が、 Aspire の現状のスタンス的にはローカル開発にフォーカスしているので可能性は低いかも?)

参考

https://learn.microsoft.com/ja-jp/dotnet/aspire/get-started/aspire-overview
https://learn.microsoft.com/ja-jp/dotnet/aspire/fundamentals/integrations-overview#hosting-integrations
https://learn.microsoft.com/ja-jp/dotnet/aspire/get-started/build-your-first-aspire-app?pivots=dotnet-cli