.NET .NET Aspire 행사
.NET .NET Aspire에서는 이벤트를 통해 다양한 앱 호스트 수명 주기동안 이벤트를 게시하고 구독할 수 있습니다. 이벤트 처리는 수명 주기 이벤트보다 더 유연합니다. 둘 다 이벤트 콜백 중 임의의 코드를 실행할 수 있지만, 이벤트 기능은 이벤트의 타이밍과 게시를 더 세부적으로 제어하고 사용자 지정 이벤트에 대한 지원을 제공합니다.
.NET .NET Aspire 이벤트 메커니즘은 📦Aspire.Hosting에 포함된 NuGet 패키지의 일부입니다. 이 패키지는 .NET.NET Aspire 앱 호스트 프로젝트의 이벤트를 게시하고 구독하는 데 사용하는 Aspire.Hosting.Eventing 네임스페이스의 인터페이스 및 클래스 집합을 제공합니다. 이벤트는 앱 호스트 자체와 그 안의 리소스에 한정됩니다.
이 문서에서는 .NET.NET Aspire이벤트 기능을 사용하는 방법을 알아봅니다.
앱 호스트 이벤트 처리
다음 이벤트는 앱 호스트에서 사용할 수 있으며 다음 순서대로 발생합니다.
- BeforeStartEvent: 이 이벤트는 앱 호스트가 시작되기 전에 발생합니다.
- AfterEndpointsAllocatedEvent: 이 이벤트는 앱 호스트가 엔드포인트를 할당한 후에 발생합니다.
- AfterResourcesCreatedEvent: 이 이벤트는 앱 호스트가 리소스를 만든 후에 발생합니다.
위의 모든 이벤트는 앱 호스트 수명 주기와 유사합니다. 즉, IDistributedApplicationLifecycleHook 구현은 이러한 이벤트를 동일하게 처리할 수 있습니다. 그러나 이벤트 API를 사용하면 이러한 이벤트가 발생할 때 임의의 코드를 실행하고 이벤트는 사용자 지정 이벤트(IDistributedApplicationEvent 인터페이스를 구현하는 모든 이벤트)를 정의할 수 있습니다.
앱 호스트 이벤트 구독
기본 제공 앱 호스트 이벤트를 구독하려면 이벤트 API를 사용합니다. 분산 애플리케이션 작성기 인스턴스가 있으면 IDistributedApplicationBuilder.Eventing 속성으로 이동하여 Subscribe<T>(Func<T,CancellationToken,Task>) API를 호출합니다. 다음 샘플 앱 호스트 Program.cs 파일을 고려합니다.
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
var builder = DistributedApplication.CreateBuilder(args);
var cache = builder.AddRedis("cache");
var apiService = builder.AddProject<Projects.AspireApp_ApiService>("apiservice");
builder.AddProject<Projects.AspireApp_Web>("webfrontend")
.WithExternalHttpEndpoints()
.WithReference(cache)
.WaitFor(cache)
.WithReference(apiService)
.WaitFor(apiService);
builder.Eventing.Subscribe<BeforeStartEvent>(
static (@event, cancellationToken) =>
{
var logger = @event.Services.GetRequiredService<ILogger<Program>>();
logger.LogInformation("1. BeforeStartEvent");
return Task.CompletedTask;
});
builder.Eventing.Subscribe<AfterEndpointsAllocatedEvent>(
static (@event, cancellationToken) =>
{
var logger = @event.Services.GetRequiredService<ILogger<Program>>();
logger.LogInformation("2. AfterEndpointsAllocatedEvent");
return Task.CompletedTask;
});
builder.Eventing.Subscribe<AfterResourcesCreatedEvent>(
static (@event, cancellationToken) =>
{
var logger = @event.Services.GetRequiredService<ILogger<Program>>();
logger.LogInformation("3. AfterResourcesCreatedEvent");
return Task.CompletedTask;
});
builder.Build().Run();
앞의 코드는 Subscribe
API에 대한 호출이 추가된 시작 템플릿을 기반으로 합니다.
Subscribe<T>
API는 이벤트에서 구독을 취소하는 데 사용할 수 있는 DistributedApplicationEventSubscription 인스턴스를 반환합니다. 일반적으로 앱 호스트가 종료되면 전체 앱이 중단되므로 이벤트 구독을 취소할 필요가 없으므로 반환된 구독을 삭제하는 것이 일반적입니다.
앱 호스트가 실행되면 .NET.NET Aspire 대시보드가 표시될 때까지 콘솔에 다음 로그 출력이 표시됩니다.
info: Program[0]
1. BeforeStartEvent
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: ..\AspireApp\AspireApp.AppHost
info: Program[0]
2. AfterEndpointsAllocatedEvent
info: Aspire.Hosting.DistributedApplication[0]
Now listening on: https://localhost:17178
info: Aspire.Hosting.DistributedApplication[0]
Login to the dashboard at https://localhost:17178/login?t=<YOUR_TOKEN>
info: Program[0]
3. AfterResourcesCreatedEvent
info: Aspire.Hosting.DistributedApplication[0]
Distributed application started. Press Ctrl+C to shut down.
로그 출력은 이벤트 처리기가 앱 호스트 수명 주기 이벤트의 순서대로 실행되는지 확인합니다. 구독 순서는 실행 순서에 영향을 주지 않습니다.
BeforeStartEvent
가 먼저 트리거되고, 그 다음에 AfterEndpointsAllocatedEvent
이 트리거되며, 마지막으로 AfterResourcesCreatedEvent
가 트리거됩니다.
리소스 이벤트 처리
앱 호스트 이벤트 외에도 리소스 이벤트를 구독할 수도 있습니다. 리소스 이벤트는 구체적으로 개별 리소스에 따라 발생합니다. 리소스 이벤트는 IDistributedApplicationResourceEvent 인터페이스의 구현으로 정의됩니다. 다음 리소스 이벤트는 나열된 순서대로 사용할 수 있습니다.
- ConnectionStringAvailableEvent: 리소스에 연결 문자열을 사용할 수 있게 되면 발생합니다.
- BeforeResourceStartedEvent: 오케스트레이터가 새 리소스를 시작하기 전에 발생합니다.
- ResourceReadyEvent: 리소스가 처음으로 준비 상태로 전환될 때 발생합니다.
리소스 이벤트 구독
리소스 이벤트를 구독하려면 이벤트 API를 사용합니다. 분산 애플리케이션 작성기 인스턴스가 있으면 IDistributedApplicationBuilder.Eventing 속성으로 이동하여 Subscribe<T>(IResource, Func<T,CancellationToken,Task>) API를 호출합니다. 다음 샘플 앱 호스트 Program.cs 파일을 고려합니다.
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
var builder = DistributedApplication.CreateBuilder(args);
var cache = builder.AddRedis("cache");
builder.Eventing.Subscribe<ResourceReadyEvent>(
cache.Resource,
static (@event, cancellationToken) =>
{
var logger = @event.Services.GetRequiredService<ILogger<Program>>();
logger.LogInformation("3. ResourceReadyEvent");
return Task.CompletedTask;
});
builder.Eventing.Subscribe<BeforeResourceStartedEvent>(
cache.Resource,
static (@event, cancellationToken) =>
{
var logger = @event.Services.GetRequiredService<ILogger<Program>>();
logger.LogInformation("2. BeforeResourceStartedEvent");
return Task.CompletedTask;
});
builder.Eventing.Subscribe<ConnectionStringAvailableEvent>(
cache.Resource,
static (@event, cancellationToken) =>
{
var logger = @event.Services.GetRequiredService<ILogger<Program>>();
logger.LogInformation("1. ConnectionStringAvailableEvent");
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
리소스의 ResourceReadyEvent
, ConnectionStringAvailableEvent
및 BeforeResourceStartedEvent
이벤트를 구독합니다.
AddRedis이 호출되면, T
가 RedisResource인 경우 IResourceBuilder<T>을 반환합니다. 리소스 작성기는 리소스를 IResourceBuilder<T>.Resource 속성으로 노출합니다. 그런 다음 해당 리소스가 Subscribe
API에 전달되어 리소스의 이벤트를 구독합니다.
앱 호스트가 실행되면 .NET.NET Aspire 대시보드가 표시될 때까지 콘솔에 다음 로그 출력이 표시됩니다.
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: ..\AspireApp\AspireApp.AppHost
info: Program[0]
1. ConnectionStringAvailableEvent
info: Program[0]
2. BeforeResourceStartedEvent
info: Program[0]
3. ResourceReadyEvent
info: Aspire.Hosting.DistributedApplication[0]
Now listening on: https://localhost:17222
info: Aspire.Hosting.DistributedApplication[0]
Login to the dashboard at https://localhost:17222/login?t=<YOUR_TOKEN>
info: Aspire.Hosting.DistributedApplication[0]
Distributed application started. Press Ctrl+C to shut down.
메모
일부 이벤트가 차단되고 있습니다. 예를 들어 BeforeResourceStartEvent
게시되면 지정된 리소스의 해당 이벤트에 대한 모든 구독 실행이 완료될 때까지 리소스 시작이 차단됩니다. 이벤트가 차단되는지 여부는 이벤트가 게시되는 방식에 따라 달라집니다(다음 섹션 참조).
이벤트 공개
기본 제공 이벤트를 구독하는 경우 앱 호스트 오케스트레이터가 사용자를 대신하여 기본 제공 이벤트를 게시하도록 관리하므로 이벤트를 직접 게시할 필요가 없습니다. 그러나 이벤트 API를 사용하여 사용자 지정 이벤트를 게시할 수 있습니다. 이벤트를 게시하려면 먼저 이벤트를 IDistributedApplicationEvent 또는 IDistributedApplicationResourceEvent 인터페이스의 구현으로 정의해야 합니다. 이벤트가 글로벌 앱 호스트 이벤트인지 또는 리소스별 이벤트인지에 따라 구현할 인터페이스를 결정해야 합니다.
그런 다음, 다음 API 중 하나를 호출하여 이벤트를 구독하고 게시할 수 있습니다.
- PublishAsync<T>(T, CancellationToken): 특정 이벤트 유형의 모든 구독자에게 이벤트를 발행합니다.
- PublishAsync<T>(T, EventDispatchBehavior, CancellationToken): 지정된 디스패치 동작을 사용하여 특정 이벤트 유형의 모든 구독자에게 이벤트를 게시합니다.
EventDispatchBehavior
제공
이벤트가 디스패치되면 구독자에게 이벤트를 디스패치하는 방법을 제어할 수 있습니다. 이벤트 디스패치 동작은 EventDispatchBehavior
열거형으로 지정됩니다. 사용할 수 있는 동작은 다음과 같습니다.
- EventDispatchBehavior.BlockingSequential: 이벤트를 순차적으로 발생시키고 모두 처리될 때까지 차단합니다.
- EventDispatchBehavior.BlockingConcurrent: 이벤트를 동시에 발생시키고 모두 처리될 때까지 차단합니다.
- EventDispatchBehavior.NonBlockingSequential: 이벤트를 순차적으로 발생시키지만, 차단하지 않습니다.
- EventDispatchBehavior.NonBlockingConcurrent: 이벤트를 동시에 트리거하지만 차단하지는 않습니다.
기본 동작은 EventDispatchBehavior.BlockingSequential
. 이 동작을 재정의하려면 PublishAsync같은 게시 API를 호출할 때 원하는 동작을 인수로 제공합니다.
.NET Aspire