AppHost イベント API
Aspire のイベント機能を使うと、様々な AppHost ライフサイクルでイベントを発行・購読できます。イベント機能はライフサイクルイベントより柔軟性が高く、どちらもイベントコールバック内で任意のコードを実行できますが、イベント機能はイベントのタイミング、発行、カスタムイベントのサポートをより細かく制御できます。
AppHost イベント
Section titled “AppHost イベント”AppHost で利用可能なイベントは、以下の順序で発生します:
BeforeStartEvent: AppHost が起動する前に発生するイベントです。ResourceEndpointsAllocatedEvent: エンドポイントが割り当てられた後に、リソースごとに発生するイベントです。AfterResourcesCreatedEvent: AppHost がリソースを作成した後に発生するイベントです。
AppHost イベントの購読
Section titled “AppHost イベントの購読”組み込み AppHost イベントを購読するには、ビルダーで便利な拡張メソッドを直接使用します。これらのメソッドは同じ IDistributedApplicationBuilder インスタンスを返すため、メソッドチェーンで呼び出せます:
using Microsoft.Extensions.DependencyInjection;using Microsoft.Extensions.Logging;
var builder = DistributedApplication.CreateBuilder(args);
builder.OnBeforeStart(static (@event, cancellationToken) =>{ var logger = @event.Services.GetRequiredService<ILogger<Program>>(); logger.LogInformation("BeforeStartEvent"); return Task.CompletedTask;});
builder.Build().Run();AppHost イベントで使用可能なビルダーレベルの拡張メソッドを以下に示します:
| メソッド | イベント |
|---|---|
OnBeforeStart | BeforeStartEvent — AppHost が起動する前に発生 |
OnBeforePublish | BeforePublishEvent — マニフェスト発行が開始する前に発生 |
OnAfterPublish | AfterPublishEvent — マニフェスト発行が完了した後に発生 |
IDistributedApplicationEventing を介して直接購読する必要がある場合 (たとえば、IDistributedApplicationEventingSubscriber 内など)、低レベルの Eventing.Subscribe<T>() API を使用できます:
builder.Eventing.Subscribe<BeforeStartEvent>( static (@event, cancellationToken) => { var logger = @event.Services.GetRequiredService<ILogger<Program>>(); logger.LogInformation("BeforeStartEvent"); return Task.CompletedTask; });
builder.Eventing.Subscribe<AfterResourcesCreatedEvent>( static (@event, cancellationToken) => { var logger = @event.Services.GetRequiredService<ILogger<Program>>(); logger.LogInformation("AfterResourcesCreatedEvent"); return Task.CompletedTask;
builder.Build().Run();import { function createBuilder(): IDistributedApplicationBuilder
Creates a new distributed application builder
createBuilder } from './.aspire/modules/aspire.mjs';
const const builder: IDistributedApplicationBuilder
builder = await function createBuilder(): IDistributedApplicationBuilder
Creates a new distributed application builder
createBuilder();
const const cache: RedisResource
cache = await const builder: IDistributedApplicationBuilder
builder.IDistributedApplicationBuilder.addRedis(name: string, options?: { port?: number; password?: string | ParameterResource;}): RedisResource (+1 overload)
Adds a Redis container to the application model.
addRedis("cache");
await const builder: IDistributedApplicationBuilder
builder.IDistributedApplicationBuilder.subscribeBeforeStart(callback: (arg: BeforeStartEvent) => Promise<void>): DistributedApplicationEventSubscription
Subscribes to the BeforeStart event, which fires before the application starts.
subscribeBeforeStart(async (event: BeforeStartEvent
event) => { var console: Console
console.Console.log(...data: any[]): void
The console.log() static method outputs a message to the console.
log("BeforeStartEvent");});
await const builder: IDistributedApplicationBuilder
builder.IDistributedApplicationBuilder.subscribeAfterResourcesCreated(callback: (arg: AfterResourcesCreatedEvent) => Promise<void>): DistributedApplicationEventSubscription
Subscribes to the AfterResourcesCreated event, which fires after all resources are created.
subscribeAfterResourcesCreated(async (event: AfterResourcesCreatedEvent
event) => { var console: Console
console.Console.log(...data: any[]): void
The console.log() static method outputs a message to the console.
log("AfterResourcesCreatedEvent");});
await const builder: IDistributedApplicationBuilder
builder.IDistributedApplicationBuilder.build(): DistributedApplication
Builds the distributed application
build().DistributedApplication.run(cancellationToken?: cancellationToken): void
Runs the distributed application
run();AppHost を実行すると、Aspire ダッシュボードが表示される頃までに、コンソールに次のログ出力が表示されるはずです:
info: Program[0] 1. BeforeStartEventinfo: Aspire.Hosting.DistributedApplication[0] Aspire version: 13.1.0info: Aspire.Hosting.DistributedApplication[0] Distributed application starting.info: Aspire.Hosting.DistributedApplication[0] Application host directory is: ../AspireApp/AspireApp.AppHostinfo: Program[0] 2. "cache" ResourceEndpointsAllocatedEventinfo: Program[0] 2. "apiservice" ResourceEndpointsAllocatedEventinfo: Program[0] 2. "webfrontend" ResourceEndpointsAllocatedEventinfo: Program[0] 2. "aspire-dashboard" ResourceEndpointsAllocatedEventinfo: Aspire.Hosting.DistributedApplication[0] Now listening on: https://localhost:17178info: Aspire.Hosting.DistributedApplication[0] Login to the dashboard at https://localhost:17178/login?t=<YOUR_TOKEN>info: Program[0] 3. AfterResourcesCreatedEventinfo: Aspire.Hosting.DistributedApplication[0] Distributed application started. Press Ctrl+C to shut down.このログ出力から、イベントハンドラーが AppHost ライフサイクルイベントの順序で実行されることが確認できます。購読の順序は実行順序に影響しません。最初に BeforeStartEvent が発生し、次に各リソースの ResourceEndpointsAllocatedEvent が続き、最後に AfterResourcesCreatedEvent が発生します。
リソースイベント
Section titled “リソースイベント”AppHost イベントに加えて、リソースイベントを購読することもできます。リソースイベントは個々のリソースに固有のものです。リソースイベントは IDistributedApplicationResourceEvent インターフェイスの実装として定義されます。以下に示す順序で利用可能なリソースイベントがあります:
InitializeResourceEvent: リソースが自身を初期化するようオーケストレーターからシグナルを送るために発生します。ResourceEndpointsAllocatedEvent: オーケストレーターがリソースのエンドポイントを割り当てたときに発生します。ConnectionStringAvailableEvent: リソースの接続文字列が利用可能になったときに発生します。BeforeResourceStartedEvent: オーケストレーターが新しいリソースを起動する前に発生します。ResourceReadyEvent: リソースが最初に準備完了状態に移行したときに発生します。
リソースイベントの購読
Section titled “リソースイベントの購読”リソースイベントを購読するには、便利な拡張メソッド (On*) を使用します。分散アプリケーションビルダーインスタンスとリソースビルダーを取得したら、そのインスタンスから目的の On* イベント API を呼び出してください。次のサンプル AppHost.cs ファイルを参照してください:
using Microsoft.Extensions.DependencyInjection;using Microsoft.Extensions.Logging;
var builder = DistributedApplication.CreateBuilder(args);
var cache = builder.AddRedis("cache");
cache.OnResourceReady(static (resource, @event, cancellationToken) => { var logger = @event.Services.GetRequiredService<ILogger<Program>>(); logger.LogInformation("5. OnResourceReady");
return Task.CompletedTask; });
cache.OnInitializeResource( static (resource, @event, cancellationToken) => { var logger = @event.Services.GetRequiredService<ILogger<Program>>(); logger.LogInformation("1. OnInitializeResource");
return Task.CompletedTask; });
cache.OnBeforeResourceStarted( static (resource, @event, cancellationToken) => { var logger = @event.Services.GetRequiredService<ILogger<Program>>(); logger.LogInformation("4. OnBeforeResourceStarted");
return Task.CompletedTask; });
cache.OnResourceEndpointsAllocated( static (resource, @event, cancellationToken) => { var logger = @event.Services.GetRequiredService<ILogger<Program>>(); logger.LogInformation("2. OnResourceEndpointsAllocated");
return Task.CompletedTask; });
cache.OnConnectionStringAvailable( static (resource, @event, cancellationToken) => { var logger = @event.Services.GetRequiredService<ILogger<Program>>(); logger.LogInformation("3. OnConnectionStringAvailable");
return Task.CompletedTask; });
var apiService = builder.AddProject<Projects.AspireApp_ApiService>("apiservice");
builder.AddProject<Projects.AspireApp_Web>("webfrontend") .WithExternalHttpEndpoints() .WithReference(cache) .WaitFor(cache) .WithReference(apiService) .WaitFor(apiService);
builder.Build().Run();上記のコードは、cache リソースの InitializeResourceEvent、ResourceReadyEvent、ResourceEndpointsAllocatedEvent、ConnectionStringAvailableEvent、BeforeResourceStartedEvent イベントを購読しています。AddRedis を呼び出すと、T が RedisResource である IResourceBuilder<T> が返されます。On* メソッドを呼び出してイベントを購読します。On* メソッドは同じ IResourceBuilder<T> インスタンスを返すため、複数の呼び出しをチェーンできます:
OnInitializeResource:InitializeResourceEventを購読します。OnResourceEndpointsAllocated:ResourceEndpointsAllocatedEventイベントを購読します。OnConnectionStringAvailable:ConnectionStringAvailableEventイベントを購読します。OnBeforeResourceStarted:BeforeResourceStartedEventイベントを購読します。OnResourceReady:ResourceReadyEventイベントを購読します。
AppHost を実行すると、Aspire ダッシュボードが表示される頃までに、コンソールに次のログ出力が表示されるはずです:
info: Aspire.Hosting.DistributedApplication[0] Aspire version: 13.1.0info: Aspire.Hosting.DistributedApplication[0] Distributed application starting.info: Aspire.Hosting.DistributedApplication[0] Application host directory is: ../AspireApp/AspireApp.AppHostinfo: Program[0] 1. OnInitializeResourceinfo: Program[0] 2. OnResourceEndpointsAllocatedinfo: Program[0] 3. OnConnectionStringAvailableinfo: Program[0] 4. OnBeforeResourceStartedinfo: Aspire.Hosting.DistributedApplication[0] Now listening on: https://localhost:17222info: Aspire.Hosting.DistributedApplication[0] Login to the dashboard at https://localhost:17222/login?t=<YOUR_TOKEN>info: Program[0] 5. OnResourceReadyinfo: Aspire.Hosting.DistributedApplication[0] Distributed application started. Press Ctrl+C to shut down.イベントの発行
Section titled “イベントの発行”組み込みイベントを購読する場合、AppHost オーケストレーターが代わりに組み込みイベントを発行するため、自分でイベントを発行する必要はありません。ただし、イベント API を使用してカスタムイベントを発行することもできます。イベントを発行するには、まず IDistributedApplicationEvent または IDistributedApplicationResourceEvent インターフェイスの実装としてイベントを定義する必要があります。イベントがグローバルな AppHost イベントかリソース固有のイベントかに基づいて、実装するインターフェイスを決定します。
次に、以下の API のいずれかを呼び出してイベントを購読および発行できます:
PublishAsync<T>(T, CancellationToken): 特定のイベント型のすべての購読者にイベントを発行します。PublishAsync<T>(T, EventDispatchBehavior, CancellationToken): 指定されたディスパッチ動作で、特定のイベント型のすべての購読者にイベントを発行します。
EventDispatchBehavior の指定
Section titled “EventDispatchBehavior の指定”イベントがディスパッチされる際、購読者へのディスパッチ方法を制御できます。イベントディスパッチ動作は EventDispatchBehavior 列挙型で指定します。以下の動作が利用可能です:
EventDispatchBehavior.BlockingSequential: イベントを順次発生させ、すべて処理されるまでブロックします。EventDispatchBehavior.BlockingConcurrent: イベントを並行して発生させ、すべて処理されるまでブロックします。EventDispatchBehavior.NonBlockingSequential: イベントを順次発生させますが、ブロックしません。EventDispatchBehavior.NonBlockingConcurrent: イベントを並行して発生させますが、ブロックしません。
デフォルトの動作は EventDispatchBehavior.BlockingSequential です。この動作をオーバーライドするには、PublishAsync などの発行 API を呼び出す際に目的の動作を引数として渡します。
イベントサブスクライバー
Section titled “イベントサブスクライバー”拡張ライブラリなど、Aspire アプリケーションモデルから直接ではなく、サービスからライフサイクルイベントにアクセスする必要がある場合があります。IDistributedApplicationEventingSubscriber を実装し、AddEventingSubscriber (または重複登録を避けたい場合は TryAddEventingSubscriber) を使用してサービスを登録できます。
using Aspire.Hosting.Eventing;using Aspire.Hosting.Lifecycle;using Microsoft.Extensions.DependencyInjection;using Microsoft.Extensions.Logging;
var builder = DistributedApplication.CreateBuilder(args);
builder.Services.AddEventingSubscriber<LifecycleLoggerSubscriber>();
builder.Build().Run();
internal sealed class LifecycleLoggerSubscriber(ILogger<LifecycleLoggerSubscriber> logger) : IDistributedApplicationEventingSubscriber{ public Task SubscribeAsync( IDistributedApplicationEventing eventing, DistributedApplicationExecutionContext executionContext, CancellationToken cancellationToken) { eventing.Subscribe<BeforeStartEvent>((@event, ct) => { logger.LogInformation("1. BeforeStartEvent"); return Task.CompletedTask; });
eventing.Subscribe<ResourceEndpointsAllocatedEvent>((@event, ct) => { logger.LogInformation("2. {Resource} ResourceEndpointsAllocatedEvent", @event.Resource.Name); return Task.CompletedTask; });
eventing.Subscribe<AfterResourcesCreatedEvent>((@event, ct) => { logger.LogInformation("3. AfterResourcesCreatedEvent"); return Task.CompletedTask; });
return Task.CompletedTask; }}このサブスクライバーアプローチにより、ビルダーのコードを最小限に保ちながら、インライン購読と同じライフサイクルの瞬間に応答できます:
AddEventingSubscriber<T>()(またはTryAddEventingSubscriber()) により、AppHost が起動するたびにサブスクライバーが参加することが保証されます。SubscribeAsyncは AppHost の実行ごとに 1 回呼び出され、IDistributedApplicationEventingとDistributedApplicationExecutionContextへのアクセスが提供されます (モデルまたは環境固有のデータが必要な場合に使用できます)。- 任意の組み込みイベント (AppHost またはリソース) や独自のカスタム
IDistributedApplicationEvent型のハンドラーを登録できます。
IDistributedApplicationLifecycleHook に以前依存していた場合は、このパターンを使用してください。ライフサイクルフック API は後方互換性のためにのみ残されており、将来のリリースで削除される予定です。
ライフサイクルフックからの移行
Section titled “ライフサイクルフックからの移行”非推奨の IDistributedApplicationLifecycleHook インターフェイスから移行する場合は、以下のマッピングを使用してください:
| 旧パターン (非推奨) | 新パターン |
|---|---|
BeforeStartAsync() | BeforeStartEvent を購読 |
AfterEndpointsAllocatedAsync() | ResourceEndpointsAllocatedEvent を購読 |
AfterResourcesCreatedAsync() | AfterResourcesCreatedEvent を購読 |
TryAddLifecycleHook<T>() | TryAddEventingSubscriber<T>() |
移行前 (非推奨):
public class MyHook : IDistributedApplicationLifecycleHook{ public Task AfterResourcesCreatedAsync( DistributedApplicationModel model, CancellationToken cancellationToken) { // イベントを処理する return Task.CompletedTask; }}
// 登録builder.Services.TryAddLifecycleHook<MyHook>();移行後 (推奨):
public class MySubscriber : IDistributedApplicationEventingSubscriber{ public Task SubscribeAsync( IDistributedApplicationEventing eventing, DistributedApplicationExecutionContext context, CancellationToken cancellationToken) { eventing.Subscribe<AfterResourcesCreatedEvent>((@event, ct) => { // context.Model を使用してイベントを処理する return Task.CompletedTask; });
return Task.CompletedTask; }}
// 登録builder.Services.TryAddEventingSubscriber<MySubscriber>();その他のイベント
Section titled “その他のイベント”コアのライフサイクルイベント以外に、Aspire は特定のシナリオ向けに追加のイベントを提供しています:
発行イベント
Section titled “発行イベント”アプリケーションの発行 (デプロイメントマニフェストの生成) 時に、次のイベントが発生します:
| イベント | 発生時 | 目的 |
|---|---|---|
BeforePublishEvent | 発行開始前 | マニフェスト生成前にリソースを検証または変更する |
AfterPublishEvent | 発行完了後 | クリーンアップや発行後のアクションを実行する |
builder.OnBeforePublish((@event, ct) =>{ // 発行前にリソースを検証する return Task.CompletedTask;});
builder.OnAfterPublish((@event, ct) =>{ // 発行後のアクション return Task.CompletedTask;});発行中に何が起こるかの詳細については、発行とデプロイの概要を参照してください。
リソース停止イベント
Section titled “リソース停止イベント”ResourceStoppedEvent は、リソースの実行が停止したときに発生します:
builder.Eventing.Subscribe<ResourceStoppedEvent>( cache, (@event, ct) => { logger.LogInformation("Resource {Name} stopped", @event.Resource.Name); return Task.CompletedTask; });