次の方法で共有


カスタム .NET.NET Aspire ホスティング統合を作成する

.NET .NET Aspire は、アプリケーションの依存関係をすばやく配置し、独自のコードに公開するために使用できる再利用可能な構成要素を提供することで、開発エクスペリエンスを向上させます。 Aspireベースのアプリケーションの主要な構成要素の 1 つは、リソースです。 次のコードを考えてみましょう。

var builder = DistributedApplication.CreateBuilder(args);

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

var db = builder.AddPostgres("pgserver")
                .AddDatabase("inventorydb");

builder.AddProject<Projects.InventoryService>("inventoryservice")
       .WithReference(redis)
       .WithReference(db);

前のコードでは、次の 4 つのリソースが表されています。

  1. cache: Redis コンテナー。
  2. pgserver: Postgres コンテナー。
  3. inventorydb: pgserverでホストされているデータベース。
  4. inventoryservice: ASP.NET Coreのアプリケーション。

開発者が書き込む .NET.NET Aspire関連するコードのほとんどは、アプリ モデルへのリソースの追加 とその間の参照の作成を中心にしています。

.NET .NET Aspire カスタム リソースの主要な要素

.NET .NET Aspire でカスタム リソースをビルドするには、次のものが必要です。

  1. IResource を実装するカスタム リソースの種類
  2. Add{CustomResource} という名前の IDistributedApplicationBuilder の拡張メソッド。ここで、{CustomResource} はカスタム リソースの名前です。

カスタム リソースでオプションの構成が必要な場合、開発者は、ビルダー パターンを使用して、これらの構成オプションを検出できるように、With* サフィックス付き拡張メソッドを実装できます。

実際の例: MailDev

カスタム リソースを開発する方法を理解するために、この記事では、MailDev用のカスタム リソースを構築する方法の例を示します。 MailDev は、開発者がアプリ内で電子メール送信動作をテストできるように設計されたローカル メール server を提供するオープンソース ツールです。 詳細については、 リポジトリの を参照してください。

この例では、作成する MailDev リソースのテスト環境として新しい .NET Aspire プロジェクトを作成します。 既存の .NET Aspire プロジェクトでカスタム リソースを作成できますが、カスタム リソースが複数の .NET Aspireベースのソリューションで使用される可能性があり、再利用可能な統合として開発する必要があるかどうかを検討することをお勧めします。

スターター プロジェクトを設定する

開発中の新しいリソースをテストするために使用する新しい .NET.NET Aspire プロジェクトを作成します。

dotnet new aspire -o MailDevResource
cd MailDevResource
dir

プロジェクトが作成されると、次を含む一覧が表示されます。

次のコマンドを実行して、プロジェクトが正常にビルドおよび実行できることを確認します。

dotnet run --project MailDevResource.AppHost/MailDevResource.AppHost.csproj

コンソールの出力は次のようになります。

Building...
info: Aspire.Hosting.DistributedApplication[0]
      Aspire version: 9.0.0
info: Aspire.Hosting.DistributedApplication[0]
      Distributed application starting.
info: Aspire.Hosting.DistributedApplication[0]
      Application host directory is:
      ..\docs-aspire\docs\extensibility\snippets\MailDevResource\MailDevResource.AppHost
info: Aspire.Hosting.DistributedApplication[0]
      Now listening on: https://localhost:17251
info: Aspire.Hosting.DistributedApplication[0]
      Login to the dashboard at https://localhost:17251/login?t=928db244c720c5022a7a9bf5cf3a3526
info: Aspire.Hosting.DistributedApplication[0]
      Distributed application started. Press Ctrl+C to shut down.

ブラウザー で [ダッシュボード] リンクを選択して、 ダッシュボードを表示します。

テスト プロジェクトの空の .NET.NET Aspire ダッシュボードのスクリーンショット。

CtrlC 押してアプリをシャットダウンします (ブラウザー タブを閉じます)。

リソース拡張機能のライブラリを作成する

.NET Aspire リソースは、.NET Aspire ホスティング ライブラリ (Aspire.Hosting) を参照するクラス ライブラリ内に含まれるクラスとメソッドにすぎません。 リソースを別のプロジェクトに配置することで、.NET.NET Aspireベースのアプリ間でリソースをより簡単に共有でき、NuGet でパッケージ化して共有できます。

  1. MailDev.Hostingという名前のクラス ライブラリ プロジェクトを作成します。

    dotnet new classlib -o MailDev.Hosting
    
  2. Aspire.Hosting をパッケージ参照としてクラス ライブラリに追加します。

    dotnet add ./MailDev.Hosting/MailDev.Hosting.csproj package Aspire.Hosting --version 9.0.0
    

    大事な

    ここで指定するバージョンは、インストールされている .NET.NET Aspire ワークロードのバージョンと一致している必要があります。

  3. MailDevResource.AppHost プロジェクトへのクラス ライブラリ参照を追加します。

    dotnet add ./MailDevResource.AppHost/MailDevResource.AppHost.csproj reference ./MailDev.Hosting/MailDev.Hosting.csproj
    
  4. クラス ライブラリ プロジェクトをソリューション ファイルに追加します。

    dotnet sln ./MailDevResource.sln add ./MailDev.Hosting/MailDev.Hosting.csproj
    

次の手順を実行したら、プロジェクトを起動できます。

dotnet run --project ./MailDevResource.AppHost/MailDevResource.AppHost.csproj

これにより、コンソールに警告が表示されます。

.\.nuget\packages\aspire.hosting.apphost\9.0.0\build\Aspire.Hosting.AppHost.targets(174,5): warning ASPIRE004: '..\MailDev.Hosting\MailDev.Hosting.csproj' is referenced by an A
spire Host project, but it is not an executable. Did you mean to set IsAspireProjectResource="false"? [D:\source\repos\docs-aspire\docs\extensibility\snippets\MailDevResource\MailDevResource.AppHost\MailDevRe
source.AppHost.csproj]

これは、.NET.NET Aspire がアプリ ホスト内のプロジェクト参照をサービス プロジェクトであるかのように扱うためです。 プロジェクト参照を非サービス プロジェクトとして扱う必要があることを .NET.NET Aspire に伝えるために、MailDev.Hosting プロジェクトへの MailDevResource.AppHostMailDevResource.AppHost.csproj ファイル参照を次のように変更します。

<ItemGroup>
  <!-- The IsAspireProjectResource attribute tells .NET Aspire to treat this 
       reference as a standard project reference and not attempt to generate
       a metadata file -->
  <ProjectReference Include="..\MailDev.Hosting\MailDev.Hosting.csproj"
                    IsAspireProjectResource="false" />
</ItemGroup>

アプリ ホストを起動すると、コンソールに警告は表示されません。

リソースの種類を定義する

MailDev.ホスティング クラス ライブラリには、リソースをアプリ ホストに追加するためのリソースの種類と拡張メソッドが含まれています。 まず、カスタム リソースを使用するときに開発者に提供するエクスペリエンスについて考える必要があります。 このカスタム リソースの場合、開発者は次のようなコードを記述できるようにする必要があります。

var builder = DistributedApplication.CreateBuilder(args);

var maildev = builder.AddMailDev("maildev");

builder.AddProject<Projects.NewsletterService>("newsletterservice")
       .WithReference(maildev);

これを実現するには、IResourceWithConnectionString を実装する MailDevResource という名前のカスタム リソースが必要です。これにより、コンシューマーは WithReference 拡張機能でそれを使用して、MailDevserver の接続の詳細を接続文字列として挿入できます。

MailDev はコンテナー リソースとして使用できるため、ContainerResource から派生して、.NET.NET Aspireのさまざまな既存のコンテナーに重点を置いた拡張機能を利用できるようにします。

MailDev.Hosting プロジェクト内の Class1.cs ファイルの内容を置き換え、ファイルの名前を次のコードで MailDevResource.cs に変更します。

// For ease of discovery, resource types should be placed in
// the Aspire.Hosting.ApplicationModel namespace. If there is
// likelihood of a conflict on the resource name consider using
// an alternative namespace.
namespace Aspire.Hosting.ApplicationModel;

public sealed class MailDevResource(string name) : ContainerResource(name), IResourceWithConnectionString
{
    // Constants used to refer to well known-endpoint names, this is specific
    // for each resource type. MailDev exposes an SMTP endpoint and a HTTP
    // endpoint.
    internal const string SmtpEndpointName = "smtp";
    internal const string HttpEndpointName = "http";

    // An EndpointReference is a core .NET Aspire type used for keeping
    // track of endpoint details in expressions. Simple literal values cannot
    // be used because endpoints are not known until containers are launched.
    private EndpointReference? _smtpReference;

    public EndpointReference SmtpEndpoint =>
        _smtpReference ??= new(this, SmtpEndpointName);

    // Required property on IResourceWithConnectionString. Represents a connection
    // string that applications can use to access the MailDev server. In this case
    // the connection string is composed of the SmtpEndpoint endpoint reference.
    public ReferenceExpression ConnectionStringExpression =>
        ReferenceExpression.Create(
            $"smtp://{SmtpEndpoint.Property(EndpointProperty.Host)}:{SmtpEndpoint.Property(EndpointProperty.Port)}"
        );
}

上記のカスタム リソースでは、EndpointReferenceReferenceExpression は、IManifestExpressionProviderIValueProviderIValueWithReferencesなど、インターフェイスのコレクションを実装するいくつかの型の例です。 これらの型とその での役割の詳細については、の技術的な詳細 参照してください。

リソース拡張機能を定義する

開発者がカスタム リソースを簡単に使用できるようにするには、AddMailDev という名前の拡張メソッドを MailDev.Hosting プロジェクトに追加する必要があります。 AddMailDev 拡張メソッドは、コンテナーとして正常に開始できるようにリソースを構成する役割を担います。

MailDev内の MailDevResourceBuilderExtensions.cs という名前の新しいファイルに次のコードを追加します。 プロジェクトのホスティング:

using Aspire.Hosting.ApplicationModel;

// Put extensions in the Aspire.Hosting namespace to ease discovery as referencing
// the .NET Aspire hosting package automatically adds this namespace.
namespace Aspire.Hosting;

public static class MailDevResourceBuilderExtensions
{
    /// <summary>
    /// Adds the <see cref="MailDevResource"/> to the given
    /// <paramref name="builder"/> instance. Uses the "2.1.0" tag.
    /// </summary>
    /// <param name="builder">The <see cref="IDistributedApplicationBuilder"/>.</param>
    /// <param name="name">The name of the resource.</param>
    /// <param name="httpPort">The HTTP port.</param>
    /// <param name="smtpPort">The SMTP port.</param>
    /// <returns>
    /// An <see cref="IResourceBuilder{MailDevResource}"/> instance that
    /// represents the added MailDev resource.
    /// </returns>
    public static IResourceBuilder<MailDevResource> AddMailDev(
        this IDistributedApplicationBuilder builder,
        string name,
        int? httpPort = null,
        int? smtpPort = null)
    {
        // The AddResource method is a core API within .NET Aspire and is
        // used by resource developers to wrap a custom resource in an
        // IResourceBuilder<T> instance. Extension methods to customize
        // the resource (if any exist) target the builder interface.
        var resource = new MailDevResource(name);

        return builder.AddResource(resource)
                      .WithImage(MailDevContainerImageTags.Image)
                      .WithImageRegistry(MailDevContainerImageTags.Registry)
                      .WithImageTag(MailDevContainerImageTags.Tag)
                      .WithHttpEndpoint(
                          targetPort: 1080,
                          port: httpPort,
                          name: MailDevResource.HttpEndpointName)
                      .WithEndpoint(
                          targetPort: 1025,
                          port: smtpPort,
                          name: MailDevResource.SmtpEndpointName);
    }
}

// This class just contains constant strings that can be updated periodically
// when new versions of the underlying container are released.
internal static class MailDevContainerImageTags
{
    internal const string Registry = "docker.io";

    internal const string Image = "maildev/maildev";

    internal const string Tag = "2.1.0";
}

アプリ ホスト内のカスタム統合を検証する

カスタム リソースの基本的な構造が完成したら、実際の AppHost プロジェクトでテストします。 MailDevResource.AppHost プロジェクトで Program.cs ファイルを開き、次のコードで更新します。

var builder = DistributedApplication.CreateBuilder(args);

var maildev = builder.AddMailDev("maildev");

builder.Build().Run();

Program.cs ファイルを更新した後、アプリ ホスト プロジェクトを起動し、ダッシュボードを開きます。

dotnet run --project ./MailDevResource.AppHost/MailDevResource.AppHost.csproj

しばらくすると、ダッシュボードに maildev リソースが実行されていることが示され、MailDev Web アプリに移動するハイパーリンクが表示されます。このハイパーリンクには、アプリが送信する各電子メールの内容が表示されます。

.NET .NET Aspire ダッシュボードは次のようになります。

MailDev リソースが .NET Aspire ダッシュボードに表示される。

MailDev Web アプリは次のようになります。

MailDev.NET Aspireによって管理されるコンテナーとして実行される Web ベースのユーザー インターフェイスです。

テスト用にアプリ ホストに .NET サービス プロジェクトを追加する

.NET Aspire が MailDev 統合を正常に起動できたら、.NET プロジェクト内の MailDev の接続情報を使用します。 .NET .NET Aspire では、ホスティング パッケージ と 1 つ以上の コンポーネント パッケージがするのが一般的です。 たとえば、次の点を考慮してください。

  • ホスティング パッケージ: アプリ モデル内のリソースを表すために使用されます。
    • Aspire.Hosting.Redis
  • コンポーネント パッケージ: client ライブラリの構成と使用に使用されます。
    • Aspire.StackExchange.Redis
    • Aspire.StackExchange.Redis.DistributedCaching
    • Aspire.StackExchange.Redis.OutputCaching

MailDev リソースの場合、.NET プラットフォームには、SmtpClient形式の簡易メール転送プロトコル (SMTP) client が既に用意されています。 この例では、わかりやすくするためにこの既存の API を使用しますが、他のリソースの種類は、開発者を支援するためにカスタム統合ライブラリの恩恵を受ける場合があります。

エンド ツー エンドのシナリオをテストするには、MailDev リソースに接続情報を挿入できる .NET プロジェクトが必要です。 Web API プロジェクトを追加します。

  1. MailDevResource.NewsletterServiceという名前の新しい .NET プロジェクトを作成します。

    dotnet new webapi --use-minimal-apis -o MailDevResource.NewsletterService
    
  2. MailDev.Hosting プロジェクトへの参照を追加します。

    dotnet add ./MailDevResource.NewsletterService/MailDevResource.NewsletterService.csproj reference ./MailDev.Hosting/MailDev.Hosting.csproj
    
  3. MailDevResource.AppHost プロジェクトへの参照を追加します。

    dotnet add ./MailDevResource.AppHost/MailDevResource.AppHost.csproj reference ./MailDevResource.NewsletterService/MailDevResource.NewsletterService.csproj
    
  4. ソリューション ファイルに新しいプロジェクトを追加します。

    dotnet sln ./MailDevResource.sln add ./MailDevResource.NewsletterService/MailDevResource.NewsletterService.csproj
    

プロジェクトが追加され、参照が更新されたら、MailDevResource.AppHost.csproj プロジェクトの Program.cs を開き、ソース ファイルを次のように更新します。

var builder = DistributedApplication.CreateBuilder(args);

var maildev = builder.AddMailDev("maildev");

builder.AddProject<Projects.MailDevResource_NewsletterService>("newsletterservice")
       .WithReference(maildev);

builder.Build().Run();

Program.cs ファイルを更新した後、アプリ ホストをもう一度起動します。 次に、ニュースレター サービスが開始され、ConnectionStrings__maildev 環境変数がプロセスに追加されたことを確認します。 [リソース] ページで、newsletterservice 行を見つけて、[の詳細] 列の [表示] リンクを選択します。

ニュースレター サービスの環境変数は、.NET.NET Aspire ダッシュボードにある。

上のスクリーンショットは、newsletterservice プロジェクトの環境変数を示しています。 ConnectionStrings__maildev 環境変数は、maildev リソースによってプロジェクトに挿入された接続文字列です。

接続文字列を使用してメッセージを送信する

ニュースレター サービス プロジェクトに挿入された SMTP 接続の詳細を使用するには、SmtpClient のインスタンスをシングルトンとして依存関係挿入コンテナーに挿入します。 シングルトン サービスを設定するには、MailDevResource.NewsletterService プロジェクトの Program.cs ファイルに次のコードを追加します。 Program クラスで、// Add services to the container コメントの直後に、次のコードを追加します。

builder.Services.AddSingleton<SmtpClient>(sp =>
{
    var smtpUri = new Uri(builder.Configuration.GetConnectionString("maildev")!);

    var smtpClient = new SmtpClient(smtpUri.Host, smtpUri.Port);

    return smtpClient;
});

ヒント

ただし、このコード スニペットは公式の SmtpClientに依存しています。この型は一部のプラットフォームでは廃止されており、他のプラットフォームでは推奨されません。 MailKitを使用したよりモダンなアプローチについては、「カスタム .NET Aspireclient 統合の作成 を参照してください。

clientをテストするには、2 つの簡単な subscribeunsubscribe POST メソッドをニュースレター サービスに追加します。 MailDevResource.NewsletterService プロジェクトの Program.cs ファイルに "weatherforecast" MapGet 呼び出しを置き換えて、ASP.NET Core ルートを設定する次のコードを追加します。

app.MapPost("/subscribe", async (SmtpClient smtpClient, string email) =>
{
    using var message = new MailMessage("newsletter@yourcompany.com", email)
    {
        Subject = "Welcome to our newsletter!",
        Body = "Thank you for subscribing to our newsletter!"
    };

    await smtpClient.SendMailAsync(message);
});

app.MapPost("/unsubscribe", async (SmtpClient smtpClient, string email) =>
{
    using var message = new MailMessage("newsletter@yourcompany.com", email)
    {
        Subject = "You are unsubscribed from our newsletter!",
        Body = "Sorry to see you go. We hope you will come back soon!"
    };

    await smtpClient.SendMailAsync(message);
});

ヒント

コード エディターで名前空間が自動的に追加されない場合は、Program.csSystem.Net.MailMicrosoft.AspNetCore.Mvc 名前空間を参照することを忘れないでください。

Program.cs ファイルが更新されたら、アプリ ホストを起動してブラウザーを使用するか、curl して次の URL をクリックします (Visual Studio を使用している場合は、.http ファイルを使用することもできます)。

POST /subscribe?email=test@test.com HTTP/1.1
Host: localhost:7251
Content-Type: application/json

この API を使用するには、curl を使用して要求を送信できます。 次の curl コマンドは、http POST 要求を subscribe エンドポイントに送信し、ニュースレターをサブスクライブするために email クエリ文字列値を想定しています。 Content-Type ヘッダーは、要求本文が JSON 形式であることを示す application/json に設定されます。

curl -H "Content-Type: application/json" --request POST https://localhost:7251/subscribe?email=test@test.com

次の API は、unsubscribe エンドポイントです。 このエンドポイントは、ニュースレターの購読を解除するために使用されます。

POST /unsubscribe?email=test@test.com HTTP/1.1
Host: localhost:7251
Content-Type: application/json

ニュースレターの登録を解除するには、次の curl コマンドを使用して、email パラメーターをクエリ文字列として unsubscribe エンドポイントに渡します。

curl -H "Content-Type: application/json" --request POST https://localhost:7251/unsubscribe?email=test@test.com

ヒント

https://localhost:7251 を正しい localhost ポート (実行中のアプリ ホストの URL) に置き換えてください。

これらの API 呼び出しで正常な応答 (HTTP 200、OK) が返された場合は、ダッシュボードの maildev リソースで選択でき、MailDev UI には SMTP エンドポイントに送信された電子メールが表示されます。

に表示される電子メール MailDev UI

技術的な詳細

以降のセクションでは、.NET.NET Aspire用のカスタム リソースを開発するときに理解しておく必要があるさまざまな技術的な詳細について説明します。

セキュリティで保護されたネットワーク

この例では、MailDev リソースは、HTTP と SMTP 経由でホスト コンピューターに公開されるコンテナー リソースです。 MailDev リソースは開発ツールであり、運用環境での使用を目的としたものではありません。 代わりに HTTPS を使用するには、「MailDev: HTTPSを構成する」を参照してください。

ネットワーク エンドポイントを公開するカスタム リソースを開発するときは、リソースのセキュリティへの影響を考慮することが重要です。 たとえば、リソースがデータベースの場合は、データベースが安全であり、接続文字列がパブリック インターネットに公開されていないことを確認することが重要です。

ReferenceExpressionEndpointReference

前のコードでは、MailDevResource には 2 つのプロパティがありました。

これらの型は、構成データを表すために .NET Aspire 全体で使用されるいくつかの種類で、.NET Aspire プロジェクトが実行されるか、Azure Developer CLI (azd)などのツールを使用してクラウドに発行されるまで確定されません。

これらの型が解決に役立つ基本的な問題は、情報が使用可能になるまで、具体的な構成情報 解決 遅延することです。

たとえば、MailDevResource は、IResourceWithConnectionString インターフェイスで必要に応じて ConnectionStringExpression というプロパティを公開します。 プロパティの型は ReferenceExpression され、挿入文字列を Create メソッドに渡すことによって作成されます。

public ReferenceExpression ConnectionStringExpression =>
    ReferenceExpression.Create(
        $"smtp://{SmtpEndpoint.Property(EndpointProperty.Host)}:{SmtpEndpoint.Property(EndpointProperty.Port)}"
    );

Create メソッドのシグネチャは次のとおりです。

public static ReferenceExpression Create(
    in ExpressionInterpolatedStringHandler handler)

これは通常の String 引数ではありません。 このメソッドは、補間文字列ハンドラー パターンを使用して、挿入文字列テンプレートとその中で参照される値をキャプチャして、カスタム処理を可能にします。 .NET .NET Aspireの場合、これらの詳細は ReferenceExpression にキャプチャされ、その中で、補間された文字列で参照される各値が使用可能になると、それらを評価することができます。

実行フローのしくみを次に示します。

  1. IResourceWithConnectionString を実装するリソースがモデルに追加されます (たとえば、AddMailDev(...))。
  2. IResourceBuilder<MailDevResource> は、IResourceWithConnectionString 実装子を処理するための特別なオーバーロードを持つ WithReference に渡されます。
  3. WithReferenceConnectionStringReference インスタンス内のリソースをラップし、オブジェクトは .NET.NET Aspire プロジェクトのビルド後に評価され、実行を開始する EnvironmentCallbackAnnotation にキャプチャされます。
  4. 接続文字列を参照するプロセスが開始されると、.NET.NET Aspire の評価が始まります。 最初に ConnectionStringReference を取得し、IValueProvider.GetValueAsyncを呼び出します。
  5. GetValueAsync メソッドは、ReferenceExpression インスタンスを取得する ConnectionStringExpression プロパティの値を取得します。
  6. その後、IValueProvider.GetValueAsync メソッドは GetValueAsync を呼び出して、以前にキャプチャした補間文字列を処理します。
  7. 補間された文字列には、EndpointReference などの他の参照型への参照も含まれているため、評価され、実際の値が置き換えられます (現時点で使用可能になりました)。

マニフェストの発行

IManifestExpressionProvider インターフェイスは、デプロイ時にリソース間で接続情報を共有する問題を解決するように設計されています。 この特定の問題の解決策については、.NET.NET Aspire 内部ループ ネットワークの概要で説明されています。 ローカル開発と同様に、多くの値はアプリを構成するために必要ですが、azd (Azure Developer CLI) などのツールを使用してアプリを展開するまでは決定できません。

この問題を解決するために、.NET.NET Aspire は、azd やその他の配置ツールが解釈するマニフェスト ファイル を生成します。 リソース間の接続情報に具体的な値を指定するのではなく、デプロイ ツールが評価する式構文が使用されます。 通常、マニフェスト ファイルは開発者には表示されませんが、手動検査用に生成することもできます。 次のコマンドは、アプリ ホストでマニフェストを生成するために使用できます。

dotnet run --project MailDevResource.AppHost/MailDevResource.AppHost.csproj -- --publisher manifest --output-path aspire-manifest.json

このコマンドは、次のようなマニフェスト ファイルを生成します。

{
  "resources": {
    "maildev": {
      "type": "container.v0",
      "connectionString": "smtp://{maildev.bindings.smtp.host}:{maildev.bindings.smtp.port}",
      "image": "docker.io/maildev/maildev:2.1.0",
      "bindings": {
        "http": {
          "scheme": "http",
          "protocol": "tcp",
          "transport": "http",
          "targetPort": 1080
        },
        "smtp": {
          "scheme": "tcp",
          "protocol": "tcp",
          "transport": "tcp",
          "targetPort": 1025
        }
      }
    },
    "newsletterservice": {
      "type": "project.v0",
      "path": "../MailDevResource.NewsletterService/MailDevResource.NewsletterService.csproj",
      "env": {
        "OTEL_DOTNET_EXPERIMENTAL_OTLP_EMIT_EXCEPTION_LOG_ATTRIBUTES": "true",
        "OTEL_DOTNET_EXPERIMENTAL_OTLP_EMIT_EVENT_LOG_ATTRIBUTES": "true",
        "OTEL_DOTNET_EXPERIMENTAL_OTLP_RETRY": "in_memory",
        "ASPNETCORE_FORWARDEDHEADERS_ENABLED": "true",
        "ConnectionStrings__maildev": "{maildev.connectionString}"
      },
      "bindings": {
        "http": {
          "scheme": "http",
          "protocol": "tcp",
          "transport": "http"
        },
        "https": {
          "scheme": "https",
          "protocol": "tcp",
          "transport": "http"
        }
      }
    }
  }
}

MailDevResource は .NET.NET Aspire のマニフェスト発行ロジック IResourceWithConnectionString 実装するため、MailDevResource はコンテナー リソースであっても、connectionString フィールドも必要です。 connectionString フィールドは、マニフェスト内の maildev リソースの他の部分を参照して、最終的な文字列を生成します。

{
    // ... other content omitted.
    "connectionString": "smtp://{maildev.bindings.smtp.host}:{maildev.bindings.smtp.port}"
}

.NET .NET Aspire は、ConnectionStringExpression を調べ、この文字列を形成する方法を知っています。これは、IManifestExpressionProvider インターフェイスを介して最終的な文字列を構築することで、IValueProvider インターフェイスの使用とほぼ同じ方法です。

MailDevResource は、ContainerResourceから派生しているため、マニフェストに自動的に含まれます。 リソース作成者は、リソース ビルダーの ExcludeFromManifest 拡張メソッドを使用して、マニフェストへの出力コンテンツを抑制することを選択できます。

public static IResourceBuilder<MailDevResource> AddMailDev(
    this IDistributedApplicationBuilder builder, 
    string name,
    int? httpPort = null,
    int? smtpPort = null)
{
    var resource = new MailDevResource(name);

    return builder.AddResource(resource)
                  .WithImage(MailDevContainerImageTags.Image)
                  .WithImageRegistry(MailDevContainerImageTags.Registry)
                  .WithImageTag(MailDevContainerImageTags.Tag)
                  .WithHttpEndpoint(
                      targetPort: 1080,
                      port: httpPort,
                      name: MailDevResource.HttpEndpointName)
                  .WithEndpoint(
                      targetPort: 1025,
                      port: smtpPort,
                      name: MailDevResource.SmtpEndpointName)
                  .ExcludeFromManifest(); // This line was added
}

リソースをマニフェストに存在させる必要があるかどうか、または抑制する必要があるかどうかについては、慎重に検討する必要があります。 リソースをマニフェストに追加する場合は、安全かつ安全に使用できるように構成する必要があります。

概要

カスタム リソースチュートリアルでは、既存のコンテナー化されたアプリケーション (MailDev) を使用するカスタム .NET Aspire リソースを作成する方法について説明しました。 その後、これを使用して、アプリ内で使用される可能性のある電子メール機能を簡単にテストできるようにして、ローカル開発エクスペリエンスを向上させます。 これらの学習は、.NET.NET Aspireベースのアプリケーションで使用できる他のカスタム リソースを構築するために適用できます。 この具体的な例にはカスタム統合は含まれていませんでしたが、開発者がリソースを簡単に使用できるようにカスタム統合を構築できます。 このシナリオでは、.NET プラットフォームの既存の SmtpClient クラスに依存して電子メールを送信することができました。

次の手順