Dela via


Händelse i .NET.NET Aspire

I .NET.NET Aspirekan du med eventing publicera och prenumerera på händelser under olika appvärdlivscykler. Händelsehantering är mer flexibel än livscykelhändelser. Båda låter dig köra godtycklig kod under händelseåteranrop, men händelsehantering ger bättre kontroll över händelsetid, publicering och har stöd för anpassade händelser.

Händelsemekanismerna i .NET.NET Aspire är en del av 📦Aspire.Hosting NuGet-paketet. Det här paketet innehåller en uppsättning gränssnitt och klasser i det Aspire.Hosting.Eventing namnområdet som du använder för att publicera och prenumerera på händelser i ditt .NET.NET Aspire värdapp-projekt. Händelseomfånget är begränsat till själva appvärden och resurserna i.

I den här artikeln får du lära dig hur du använder händelsefunktionerna i .NET.NET Aspire.

Händelsehantering för appvärd

Följande händelser är tillgängliga i appvärden och sker i följande ordning:

  1. BeforeStartEvent: Den här händelsen utlöses innan appvärden startar.
  2. AfterEndpointsAllocatedEvent: Den här händelsen utlöses efter att appvärden har allokerat slutpunkter.
  3. AfterResourcesCreatedEvent: Den här händelsen utlöses efter att appvärden har skapat resurser.

Alla föregående händelser liknar applikationsvärdens livscykler. En implementering av IDistributedApplicationLifecycleHook skulle kunna hantera dessa händelser på samma sätt. Med händelse-API:et kan du dock köra godtycklig kod när dessa händelser aktiveras och händelsedefiniera anpassade händelser – alla händelser som implementerar IDistributedApplicationEvent-gränssnittet.

Prenumerera på appvärdhändelser

Om du vill prenumerera på de inbyggda appvärdhändelserna använder du händelse-API:et. När du har en distribuerad application builder-instans går du upp till egenskapen IDistributedApplicationBuilder.Eventing och anropar Subscribe<T>(Func<T,CancellationToken,Task>)-API:et. Överväg följande exempelapp värd filen 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();

Föregående kod baseras på startmallen med tillägg av anropen till Subscribe-API:et. Subscribe<T>-API:et returnerar en DistributedApplicationEventSubscription instans som du kan använda för att avbryta prenumerationen på händelsen. Det är vanligt att ta bort de returnerade prenumerationerna, eftersom det sällan är nödvändigt att säga upp prenumerationer på händelser när hela appen stängs ner i samband med att appvärden stängs av.

När appvärden körs bör du se följande loggutdata i konsolen när .NET.NET Aspire-instrumentpanelen visas:

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.

Loggdata bekräftar att händelsehanterare körs i den ordning appens värd livscykelhändelser. Prenumerationsordningen påverkar inte körningsordningen. BeforeStartEvent utlöses först, följt av AfterEndpointsAllocatedEventoch slutligen AfterResourcesCreatedEvent.

Resurshändelse

Förutom appvärdhändelserna kan du även prenumerera på resurshändelser. Resurshändelser genereras som är specifika för en enskild resurs. Resurshändelser definieras som implementeringar av IDistributedApplicationResourceEvent-gränssnittet. Följande resurshändelser är tillgängliga i den angivna ordningen:

  1. ConnectionStringAvailableEvent: Utlöses när en anslutningssträng blir tillgänglig för en resurs.
  2. BeforeResourceStartedEvent: Upphöjt innan orkestreringshanteraren startar en ny resurs.
  3. ResourceReadyEvent: Utlöses när en resurs först övergår till ett redo tillstånd.

Prenumerera på resurshändelser

Om du vill prenumerera på resurshändelser använder du händelse-API:et. När du har en distribuerad application builder-instans går du upp till egenskapen IDistributedApplicationBuilder.Eventing och anropar Subscribe<T>(IResource, Func<T,CancellationToken,Task>)-API:et. Överväg följande exempelappens värd fil 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();

Föregående kod prenumererar på händelserna ResourceReadyEvent, ConnectionStringAvailableEventoch BeforeResourceStartedEvent på resursen cache. När AddRedis anropas returneras en IResourceBuilder<T> där T är en RedisResource. Resursbyggaren exponerar resursen som egenskapen IResourceBuilder<T>.Resource. Resursen i fråga skickas sedan till Subscribe-API:et för att prenumerera på händelserna på resursen.

När appvärden körs bör du se följande loggutdata i konsolen när .NET.NET Aspire-instrumentpanelen visas:

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.

Obs

Vissa händelser är blockerande. När BeforeResourceStartEvent till exempel publiceras blockeras resursens start tills alla prenumerationer för händelsen på en viss resurs har slutförts. Om en händelse blockerar eller inte beror på hur den publiceras (se följande avsnitt).

Publicera händelser

När du prenumererar på någon av de inbyggda händelserna behöver du inte publicera händelsen själv när appens värdorkestrator hanterar publiceringen av inbyggda händelser åt dig. Du kan dock publicera anpassade händelser med händelse-API:et. Om du vill publicera en händelse måste du först definiera en händelse som en implementering av antingen IDistributedApplicationEvent- eller IDistributedApplicationResourceEvent-gränssnittet. Du måste avgöra vilket gränssnitt som ska implementeras baserat på om händelsen är en global appvärdhändelse eller en resursspecifik händelse.

Sedan kan du prenumerera och publicera händelsen genom att anropa något av följande API:er:

Ange en EventDispatchBehavior

När händelser skickas kan du styra hur händelserna skickas till prenumeranter. Beteendet för händelsesändning anges med EventDispatchBehavior enumeration. Följande beteenden är tillgängliga:

Standardbeteendet är EventDispatchBehavior.BlockingSequential. Om du vill åsidosätta det här beteendet anger du önskat beteende som ett argument när du anropar ett publicerings-API som PublishAsync.