Freigeben über


übersicht über .NET.NET Aspire Orchestrierung

.NET .NET Aspire stellt APIs zum Ausdrücken von Ressourcen und Abhängigkeiten in Ihrer verteilten Anwendung bereit. Zusätzlich zu diesen APIs gibt es Werkzeuge, die mehrere überzeugende Szenarien ermöglichen. Der Orchestrator ist für lokale Entwicklungszwecke vorgesehen und wird in Produktionsumgebungen nicht unterstützt.

Bevor Sie fortfahren, sollten Sie einige allgemeine Termini in .NET.NET Aspirebedenken.

  • App-Modell: Eine Sammlung von Ressourcen, die Ihre verteilte Anwendung (DistributedApplication) bilden, die im Aspire.Hosting.ApplicationModel-Namespace definiert ist. Eine formellere Definition finden Sie unter Definieren des App-Modells.
  • App-Host/Orchestrator-Projekt: Das .NET-Projekt, das das App-Modellkoordiniert, benannt mit dem *.AppHost Suffix (nach Konvention).
  • Ressource: Eine Ressource ist ein abhängiger Teil einer Anwendung, z. B. ein .NET Projekt, Container, ausführbare Datei, Datenbank, Cache oder Clouddienst. Er stellt einen beliebigen Teil der Anwendung dar, der verwaltet oder referenziert werden kann.
  • Integration: Eine Integration ist ein NuGet-Paket für den App-Host, der eine Ressource modelliert, oder ein Paket, das eine client für die Verwendung in einer verbrauchenden App konfiguriert. Weitere Informationen finden Sie unter .NET.NET Aspire Integrationsübersicht.
  • Referenz-: Eine Referenz definiert eine Verbindung zwischen Ressourcen, die als Abhängigkeit mithilfe der WithReference-API ausgedrückt wird. Weitere Informationen finden Sie unter Referenzressourcen oder Verweisen auf vorhandene Ressourcen.

Anmerkung

.NET .NET AspireOrchestrierung ist darauf ausgelegt, Ihre lokale Entwicklungs--Erfahrung zu verbessern, indem sie die Verwaltung der Konfiguration und der Verbindungen Ihrer Cloud-nativen App vereinfacht. Obwohl es ein unschätzbares Tool für die Entwicklung ist, ist es nicht dafür vorgesehen, Produktionsumgebungssysteme wie Kuberneteszu ersetzen, die speziell dafür konzipiert sind, in diesem Kontext hervorragende Leistungen zu erbringen.

Definieren des App-Modells

.NET .NET Aspire ermöglicht es Ihnen, Ihre verteilten Anwendungen nahtlos zu erstellen, bereitzustellen, bereitzustellen, zu konfigurieren, zu testen, auszuführen und zu beobachten. All diese Funktionen werden durch die Verwendung eines App-Modells erreicht, das die Ressourcen in Ihrer .NET.NET Aspire Lösung und deren Beziehungen umschreibt. Diese Ressourcen umfassen Projekte, ausführbare Dateien, Container und externe Dienste und Cloudressourcen, von denen Ihre App abhängt. Innerhalb jeder .NET.NET Aspire Lösung gibt es ein bestimmtes App-Hostprojekt, in dem das App-Modell genau mithilfe von Methoden definiert wird, die für die IDistributedApplicationBuilderverfügbar sind. Dieser Generator wird durch Aufrufen von DistributedApplication.CreateBuilderabgerufen.

// Create a new app model builder
var builder = DistributedApplication.CreateBuilder(args);

// TODO:
//   Add resources to the app model
//   Express dependencies between resources

builder.Build().Run();

App-Hostprojekt

Das App-Hostprojekt behandelt die Ausführung aller Projekte, die Teil des .NET.NET Aspire Projekts sind. Mit anderen Worten: Sie ist dafür verantwortlich, alle Apps im App-Modell zu koordinieren. Das Projekt selbst ist ein .NET ausführbares Projekt, das auf das 📦Aspire.Hosting.AppHost NuGet-Paket verweist, setzt die IsAspireHost Eigenschaft auf truefest und verweist auf das .NET.NET Aspire SDK-.

<Project Sdk="Microsoft.NET.Sdk">

    <Sdk Name="Aspire.AppHost.Sdk" Version="9.0.0" />
    
    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net9.0</TargetFramework>
        <IsAspireHost>true</IsAspireHost>
        <!-- Omitted for brevity -->
    </PropertyGroup>

    <ItemGroup>
        <PackageReference Include="Aspire.Hosting.AppHost" Version="9.0.0" />
    </ItemGroup>

    <!-- Omitted for brevity -->

</Project>

Der folgende Code beschreibt einen App-Host Program mit zwei Projektverweisen und einem Redis Cache:

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.Build().Run();

Der vorherige Code:

  • Erstellt einen neuen App-Modell-Generator mithilfe der CreateBuilder-Methode.
  • Fügt eine Rediscache Ressource mit dem Namen "cache" mithilfe der AddRedis-Methode hinzu.
  • Fügt eine Projektressource namens "apiservice" mithilfe der AddProject-Methode hinzu.
  • Fügt eine Projektressource namens "webfrontend" mithilfe der AddProject-Methode hinzu.
    • Gibt an, dass das Projekt über externe HTTP-Endpunkte mit der WithExternalHttpEndpoints-Methode verfügt.
    • Fügt einen Verweis auf die cache-Ressource hinzu und wartet darauf, dass sie mithilfe der Methoden WithReference und WaitFor bereitgestellt wird.
    • Fügt einen Verweis auf die apiservice-Ressource hinzu und wartet darauf, dass sie mithilfe der Methoden WithReference und WaitFor bereitgestellt wird.
  • Erstellt und führt das App-Modell mit den Methoden Build und Run aus.

Im Beispielcode wird die .NET AspireRedis Hosting-Integrationverwendet.

Um die Beziehung zwischen dem App-Hostprojekt und den beschriebenen Ressourcen zu visualisieren, ziehen Sie das folgende Diagramm in Betracht:

Die Beziehung zwischen den Projekten in der .NET.NET Aspire Starter-Anwendungsvorlage.

Jede Ressource muss eindeutig benannt werden. Dieses Diagramm zeigt jede Ressource und die Beziehungen zwischen ihnen. Die Containerressource heißt "cache", und die Projektressourcen heißen "apiservice" und "webfrontend". Das Web-Frontend-Projekt verweist auf die Cache- und API-Dienstprojekte. Wenn Sie Verweise auf diese Weise ausdrücken, sagt das Web-Frontend-Projekt, dass es von diesen beiden Ressourcen abhängt, dem „Cache“ bzw. „Apiservice“.

Integrierte Ressourcentypen

.NET .NET Aspire Projekte bestehen aus einer Reihe von Ressourcen. Die primären Basisressourcentypen im NuGet-Paket 📦Aspire.Hosting.AppHost werden in der folgenden Tabelle beschrieben.

Methode Ressourcentyp Beschreibung
AddProject ProjectResource Ein .NET Projekt, z. B. eine ASP.NET Core Web-App.
AddContainer ContainerResource Ein Containerbild, zum Beispiel ein Docker-Bild.
AddExecutable ExecutableResource Eine ausführbare Datei, z. B. eine Node.js App.
AddParameter ParameterResource Eine Parameterressource, die verwendet werden kann, um externe Parameter auszudrücken.

Projektressourcen stellen .NET Projekte dar, die Teil des App-Modells sind. Wenn Sie dem App-Hostprojekt einen Projektverweis hinzufügen, generiert das .NET.NET Aspire SDK für jedes referenzierte Projekt einen Typ im Projects Namespace. Weitere Informationen finden Sie unter .NET.NET Aspire SDK: Projektverweise.

Um dem App-Modell ein Projekt hinzuzufügen, verwenden Sie die AddProject-Methode:

var builder = DistributedApplication.CreateBuilder(args);

// Adds the project "apiservice" of type "Projects.AspireApp_ApiService".
var apiservice = builder.AddProject<Projects.AspireApp_ApiService>("apiservice");

Projekte können repliziert und skaliert werden, indem dem App-Modell mehrere Instanzen desselben Projekts hinzugefügt werden. Verwenden Sie zum Konfigurieren von Replikaten die WithReplicas Methode:

var builder = DistributedApplication.CreateBuilder(args);

// Adds the project "apiservice" of type "Projects.AspireApp_ApiService".
var apiservice = builder.AddProject<Projects.AspireApp_ApiService>("apiservice")
                        .WithReplicas(3);

Im vorherigen Code werden dem App-Modell drei Replikate der Projektressource "apiservice" hinzugefügt. Weitere Informationen finden Sie unter .NET.NET Aspire Dashboard: Ressourcenreplikate.

Referenzressourcen

Ein Verweis stellt eine Abhängigkeit zwischen Ressourcen dar. Beispielsweise können Sie sich wahrscheinlich ein Szenario vorstellen, in dem ein Web-Frontend von einem Redis-Cache abhängt. Betrachten Sie den folgenden Beispiel-App-Host Program C#-Code:

var builder = DistributedApplication.CreateBuilder(args);

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

builder.AddProject<Projects.AspireApp_Web>("webfrontend")
       .WithReference(cache);

Die Projektressource "webfrontend" verwendet WithReference, um eine Abhängigkeit von der Containerressource "cache" hinzuzufügen. Diese Abhängigkeiten können Verbindungszeichenfolgen oder Dienstermittlung Informationen darstellen. Im vorherigen Beispiel wird eine Umgebungsvariable ConnectionStrings__cache eingesetzt. Diese Umgebungsvariable enthält eine Verbindungszeichenfolge, die vom webfrontend zum Herstellen einer Verbindung mit Redis über die .NET AspireRedis Integrationverwendet wird, z. B. ConnectionStrings__cache="localhost:62354".

Warten auf Ressourcen

In einigen Fällen sollten Sie warten, bis eine Ressource bereit ist, bevor Sie eine andere Ressource starten. Sie können z. B. warten, bis eine Datenbank bereit ist, bevor Sie eine API starten, die davon abhängt. Verwenden Sie die WaitFor-Methode, um diese Abhängigkeit auszudrücken:

var builder = DistributedApplication.CreateBuilder(args);

var postgres = builder.AddPostgres("postgres");
var postgresdb = postgres.AddDatabase("postgresdb");

builder.AddProject<Projects.AspireApp_ApiService>("apiservice")
       .WithReference(postgresdb)
       .WaitFor(postgresdb);

Im vorherigen Code wartet die Projektressource "apiservice" darauf, dass die Datenbankressource "postgresdb" den Zustand KnownResourceStates.Runningerreicht. Der Beispielcode zeigt die .NET AspirePostgreSQL Integration, aber dasselbe Muster kann auf andere Ressourcen angewendet werden.

In anderen Fällen kann es erforderlich sein, auf den Abschluss einer Ressource zu warten, entweder KnownResourceStates.Exited oder KnownResourceStates.Finished, bevor die abhängige Ressource gestartet wird. Verwenden Sie das WaitForCompletion-Verfahren, um zu warten, bis eine Ressource abgeschlossen ist.

var builder = DistributedApplication.CreateBuilder(args);

var postgres = builder.AddPostgres("postgres");
var postgresdb = postgres.AddDatabase("postgresdb");

var migration = builder.AddProject<Projects.AspireApp_Migration>("migration")
                       .WithReference(postgresdb)
                       .WaitFor(postgresdb);

builder.AddProject<Projects.AspireApp_ApiService>("apiservice")
       .WithReference(postgresdb)
       .WaitForCompletion(migration);

Im vorherigen Code wartet die Projektressource "apiservice" darauf, dass die Projektressource "migration" bis zur vollständigen Ausführung läuft, bevor sie startet. Die Ressource "Migration" wartet darauf, dass die Datenbankressource "postgresdb" den Zustand KnownResourceStates.Runningerreicht. Dies kann in Szenarien hilfreich sein, in denen Sie eine Datenbankmigration ausführen möchten, bevor Sie beispielsweise den API-Dienst starten.

APIs zum Hinzufügen und Ausdrücken von Ressourcen

.NET .NET Aspire Hostingintegrationen und client Integrationen werden beide als NuGet-Pakete bereitgestellt, dienen jedoch unterschiedlichen Zwecken. Während client Integrationenclient Bibliothekskonfiguration für die Nutzung von Apps außerhalb des App-Hosts bereitstellen, Hostintegrationen APIs zum Ausdrücken von Ressourcen und Abhängigkeiten innerhalb des App-Hosts bereitstellen. Weitere Informationen finden Sie unter .NET.NET Aspire Integrationsübersicht: Integrationsaufgaben.

Express-Containerressourcen

Um eine ContainerResource auszudrücken, fügen Sie sie zu einer IDistributedApplicationBuilder Instanz hinzu, indem Sie die AddContainer-Methode aufrufen:

var builder = DistributedApplication.CreateBuilder(args);

var ollama = builder.AddContainer("ollama", "ollama/ollama")
    .WithBindMount("ollama", "/root/.ollama")
    .WithBindMount("./ollamaconfig", "/usr/config")
    .WithHttpEndpoint(port: 11434, targetPort: 11434, name: "ollama")
    .WithEntrypoint("/usr/config/entrypoint.sh")
    .WithContainerRuntimeArgs("--gpus=all");

Weitere Informationen finden Sie in GPU-Unterstützung in Docker Desktop.

Der vorangehende Code fügt eine Containerressource namens "ollama" mit dem Image ollama/ollamahinzu. Die Containerressource ist mit mehreren Bind-Mounts, einem benannten HTTP-Endpunkt, einem Entry-Point konfiguriert, der in Unix-Shellskript aufgelöst wird, und Containerausführungsargumenten mit der WithContainerRuntimeArgs-Methode.

Ressourcen von Containern anpassen

Alle ContainerResource Unterklassen können an Ihre spezifischen Anforderungen angepasst werden. Dies kann nützlich sein, wenn Sie eine Hostintegration verwenden, die eine Containerressource modelliert, aber Änderungen erfordert. Wenn Sie über eine IResourceBuilder<ContainerResource> verfügen, können Sie Aufrufe an eine der verfügbaren APIs verketten, um die Containerressource zu ändern. .NET .NET Aspire Containerressourcen verweisen normalerweise auf festgelegte Tags, aber Sie könnten stattdessen das latest-Tag verwenden.

Um dies zu veranschaulichen, stellen Sie sich ein Szenario vor, in dem Sie die .NET AspireRedis Integrationverwenden. Wenn die Redis-Integration auf das 7.4-Tag basiert und Sie stattdessen das latest-Tag verwenden möchten, können Sie einen Aufruf an die WithImageTag-API verketten:

var builder = DistributedApplication.CreateBuilder(args);

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

// Instead of using the "7.4" tag, the "cache" 
// container resource now uses the "latest" tag.

Weitere Informationen und zusätzliche APIs finden Sie unter ContainerResourceBuilderExtensions.

Lebenszyklus von Containerressourcen

Wenn der App-Host ausgeführt wird, wird die ContainerResource verwendet, um zu bestimmen, welches Containerimage erstellt und gestartet werden soll. Unter der Haube führt .NET Aspire den Container mithilfe des definierten Containerimages aus, indem Aufrufe an die entsprechende OCI-kompatible Containerlaufzeit delegiert werden, entweder Docker oder Podman. Die folgenden Befehle werden verwendet:

Zunächst wird der Container mithilfe des Befehls docker container create erstellt. Anschließend wird der Container mit dem Befehl docker container start gestartet.

Diese Befehle werden anstelle von docker run verwendet, um angefügte Containernetzwerke, Volumes und Ports zu verwalten. Das Aufrufen dieser Befehle in dieser Reihenfolge ermöglicht es, dass eine beliebige IP-Adresse oder Netzwerkkonfiguration bereits beim ersten Start vorhanden ist.

Über die Basisressourcentypen ProjectResource, ContainerResourceund ExecutableResourcehinaus stellt .NET.NET Aspire Erweiterungsmethoden bereit, um Ihrem App-Modell allgemeine Ressourcen hinzuzufügen. Weitere Informationen finden Sie unter Hosting-Integrationen.

Lebensdauer der Containerressource

Standardmäßig verwenden Containerressourcen die Lebensdauer der Sitzung des Containers. Dies bedeutet, dass der Container bei jedem Start des App-Hostprozesses erstellt und gestartet wird. Wenn der App-Host beendet wird, wird der Container beendet und entfernt. Containerressourcen können sich für eine beständigen Lebensdauer anmelden, um unnötige Neustarts zu vermeiden und den permanenten Containerzustand zu verwenden. Rufen Sie dazu nacheinander die ContainerResourceBuilderExtensions.WithLifetime-API auf und übergeben Sie ContainerLifetime.Persistent:

var builder = DistributedApplication.CreateBuilder(args);

var ollama = builder.AddContainer("ollama", "ollama/ollama")
    .WithLifetime(ContainerLifetime.Persistent);

Der vorangehende Code fügt eine Containerressource namens "ollama" mit dem Image "ollama/ollama" und einer persistenten Lebensdauer hinzu.

Verbindungsstring- und Endpunktverweise

Es ist üblich, Abhängigkeiten zwischen Projektressourcen auszudrücken. Betrachten Sie den folgenden Beispielcode:

var builder = DistributedApplication.CreateBuilder(args);

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

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

builder.AddProject<Projects.AspireApp_Web>("webfrontend")
       .WithReference(cache)
       .WithReference(apiservice);

Project-to-Project-Verweise werden anders behandelt als Ressourcen mit gut definierten Verbindungszeichenfolgen. Anstatt die Verbindungszeichenfolge in die Ressource "webfrontend" einzufügen, werden Umgebungsvariablen zur Unterstützung der Dienstermittlung eingefügt.

Methode Umgebungsvariable
WithReference(cache) ConnectionStrings__cache="localhost:62354"
WithReference(apiservice) services__apiservice__http__0="http://localhost:5455"
services__apiservice__https__0="https://localhost:7356"

Das Hinzufügen eines Verweises auf das "apiservice"-Projekt führt dazu, dass Dienstermittlungsumgebungsvariablen dem Frontend hinzugefügt werden. Dies liegt daran, dass die Projekt-zu-Projekt-Kommunikation in der Regel über HTTP/gRPC erfolgt. Weitere Informationen finden Sie unter .NET.NET Aspire Serviceerkennung.

Um bestimmte Endpunkte aus einem ContainerResource oder einem ExecutableResourceabzurufen, verwenden Sie eine der folgenden Endpunkt-APIs:

Rufen Sie dann die GetEndpoint-API auf, um den Endpunkt abzurufen, der zum Verweisen auf den Endpunkt in der WithReference-Methode verwendet werden kann:

var builder = DistributedApplication.CreateBuilder(args);

var customContainer = builder.AddContainer("myapp", "mycustomcontainer")
                             .WithHttpEndpoint(port: 9043, name: "endpoint");

var endpoint = customContainer.GetEndpoint("endpoint");

var apiservice = builder.AddProject<Projects.AspireApp_ApiService>("apiservice")
                        .WithReference(endpoint);
Methode Umgebungsvariable
WithReference(endpoint) services__myapp__endpoint__0=https://localhost:9043

Der parameter port ist der Port, auf den der Container lauscht. Weitere Informationen über Containerhäfen finden Sie unter Containerhäfen. Weitere Informationen zur Dienstentdeckung finden Sie unter .NET.NET Aspire Dienstentdeckung.

Variablenformat der Dienstendpunktumgebung

Im vorherigen Abschnitt wird die WithReference-Methode verwendet, um Abhängigkeiten zwischen Ressourcen auszudrücken. Wenn Dienstendpunkte dazu führen, dass Umgebungsvariablen in die abhängige Ressource eingefügt werden, ist das Format möglicherweise nicht offensichtlich. Dieser Abschnitt enthält Details zu diesem Format.

Wenn eine Ressource von einer anderen Ressource abhängt, fügt der App-Host Umgebungsvariablen in die abhängige Ressource ein. Diese Umgebungsvariablen konfigurieren die abhängige Ressource, um eine Verbindung mit der Ressource herzustellen, von der sie abhängt. Das Format der Umgebungsvariablen ist spezifisch für .NET.NET Aspire und expressiert Dienstendpunkte auf eine Weise, die mit Service Discoverykompatibel ist.

Variablennamen der Dienstendpunktumgebung werden in der Reihenfolge mit services__ (doppelter Unterstrich), dann dem Dienstnamen, dem Endpunktnamen und schließlich dem Index vorangestellt. Der Index unterstützt mehrere Endpunkte für einen einzelnen Dienst, beginnend mit 0 für den ersten Endpunkt und wird für jeden weiteren Endpunkt inkrementiert.

Betrachten Sie die folgenden Beispiele für Umgebungsvariablen:

services__apiservice__http__0

Die vorangehende Umgebungsvariable drückt den ersten HTTP-Endpunkt für den apiservice-Dienst aus. Der Wert der Umgebungsvariable ist die URL des Dienstendpunkts. Ein benannter Endpunkt kann wie folgt ausgedrückt werden:

services__apiservice__myendpoint__0

Im vorherigen Beispiel verfügt der apiservice Dienst über einen benannten Endpunkt namens myendpoint. Der Wert der Umgebungsvariable ist die URL des Dienstendpunkts.

Verweisen auf vorhandene Ressourcen

Einige Situationen erfordern, dass Sie auf eine bestehende Ressource verweisen, zum Beispiel eine, die bei einem Cloud-Anbieter bereitgestellt wird. Zum Beispiel könnten Sie auf eine Azure-Datenbank verweisen. In diesem Fall verlassen Sie sich auf den Ausführungskontext, um dynamisch zu bestimmen, ob der Anwendungshost im Modus "Ausführen" oder "Veröffentlichen" läuft. Wenn Sie lokal arbeiten und auf eine Cloud-Ressource zugreifen möchten, können Sie die IsRunMode-Eigenschaft verwenden, um die Referenz bedingungsgesteuert hinzuzufügen. Sie können stattdessen die Ressource im Veröffentlichungsmodus erstellen. Einige Hostingintegrationen, unterstützen die Bereitstellung einer Verbindungszeichenfolge direkt, die verwendet werden kann, um auf eine vorhandene Ressource zu verweisen.

Ebenso kann es Anwendungsfälle geben, in denen Sie .NET.NET Aspire in eine vorhandene Lösung integrieren möchten. Ein gängiger Ansatz ist das Hinzufügen des .NET.NET Aspire App-Hostprojekts zu einer vorhandenen Lösung. Innerhalb Ihres App-Hosts definieren Sie Abhängigkeiten, indem Sie dem App-Host Projektverweise hinzufügen und das App-Modellerweitern. Beispielsweise kann ein Projekt von einem anderen abhängen. Diese Abhängigkeiten werden mithilfe der WithReference-Methode ausgedrückt. Weitere Informationen finden Sie unter Hinzufügen von .NET Aspire zu einer vorhandenen .NET App-.

Lebenszyklen des App-Hosts

Der .NET.NET Aspire-App-Host stellt mehrere Lebenszyklen zur Verfügung, in die Sie durch Implementierung der IDistributedApplicationLifecycleHook-Schnittstelle eingreifen können. Die folgenden Lebenszyklusmethoden sind verfügbar:

Bestellung Methode Beschreibung
1 BeforeStartAsync Wird ausgeführt, bevor die verteilte Anwendung gestartet wird.
2 AfterEndpointsAllocatedAsync Wird ausgeführt, nachdem der Orchestrator Endpunkte für Ressourcen im Anwendungsmodell zuordnet.
3 AfterResourcesCreatedAsync Wird ausgeführt, nachdem die Ressource vom Orchestrator erstellt wurde.

Während der App-Host Lebenszyklus-Hooks bereitstellt, möchten Sie vielleicht benutzerdefinierte Ereignisse registrieren. Weitere Informationen finden Sie unter Ereignissteuerung in .NET.NET Aspire.

Einen Lebenszyklus-Hook registrieren

Um einen Lebenszyklus-Hook zu registrieren, implementieren Sie die Schnittstelle IDistributedApplicationLifecycleHook und registrieren Sie den Hook mithilfe der API AddLifecycleHook beim App-Host.

using Aspire.Hosting.Lifecycle;
using Microsoft.Extensions.Logging;

var builder = DistributedApplication.CreateBuilder(args);

builder.Services.AddLifecycleHook<LifecycleLogger>();

builder.Build().Run();

internal sealed class LifecycleLogger(ILogger<LifecycleLogger> logger)
    : IDistributedApplicationLifecycleHook
{
    public Task BeforeStartAsync(
        DistributedApplicationModel appModel, CancellationToken cancellationToken = default)
    {
        logger.LogInformation("BeforeStartAsync");
        return Task.CompletedTask;
    }

    public Task AfterEndpointsAllocatedAsync(
        DistributedApplicationModel appModel, CancellationToken cancellationToken = default)
    {
        logger.LogInformation("AfterEndpointsAllocatedAsync");
        return Task.CompletedTask;
    }

    public Task AfterResourcesCreatedAsync(
        DistributedApplicationModel appModel, CancellationToken cancellationToken = default)
    {
        logger.LogInformation("AfterResourcesCreatedAsync");
        return Task.CompletedTask;
    }
}

Der vorherige Code:

Wenn dieser App-Host ausgeführt wird, wird der Lebenszyklus-Hook für jedes Ereignis aktiviert. Die folgende Ausgabe wird generiert:

info: LifecycleLogger[0]
      BeforeStartAsync
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: LifecycleLogger[0]
      AfterEndpointsAllocatedAsync
info: Aspire.Hosting.DistributedApplication[0]
      Now listening on: https://localhost:17043
info: Aspire.Hosting.DistributedApplication[0]
      Login to the dashboard at https://localhost:17043/login?t=d80f598bc8a64c7ee97328a1cbd55d72
info: LifecycleLogger[0]
      AfterResourcesCreatedAsync
info: Aspire.Hosting.DistributedApplication[0]
      Distributed application started. Press Ctrl+C to shut down.

Die bevorzugte Methode, um sich in den App-Host-Lebenszyklus zu integrieren, besteht darin, die Ereignis-API zu verwenden. Weitere Informationen finden Sie unter Ereignissteuerung in .NET.NET Aspire.

Ausführungskontext

Die IDistributedApplicationBuilder macht einen Ausführungskontext (DistributedApplicationExecutionContext) verfügbar, der Informationen zur aktuellen Ausführung des App-Hosts bereitstellt. Dieser Kontext kann verwendet werden, um zu überprüfen, ob der App-Host im Modus 'Ausführen' oder als Teil eines Veröffentlichungsvorgangs ausgeführt wird. Berücksichtigen Sie die folgenden Eigenschaften:

  • IsRunMode: Gibt true zurück, wenn der aktuelle Vorgang ausgeführt wird.
  • IsPublishMode: Gibt true zurück, wenn der aktuelle Vorgang eine Veröffentlichung ist.

Diese Informationen können nützlich sein, wenn Sie Code basierend auf dem aktuellen Vorgang bedingt ausführen möchten. Betrachten Sie das folgende Beispiel, das die Verwendung der IsRunMode-Eigenschaft veranschaulicht. In diesem Fall wird eine Erweiterungsmethode verwendet, um einen stabilen Knotennamen für RabbitMQ für lokale Entwicklungsläufe zu generieren.

private static IResourceBuilder<RabbitMQServerResource> RunWithStableNodeName(
    this IResourceBuilder<RabbitMQServerResource> builder)
{
    if (builder.ApplicationBuilder.ExecutionContext.IsRunMode)
    {
        builder.WithEnvironment(context =>
        {
            // Set a stable node name so queue storage is consistent between sessions
            var nodeName = $"{builder.Resource.Name}@localhost";
            context.EnvironmentVariables["RABBITMQ_NODENAME"] = nodeName;
        });
    }

    return builder;
}

Der Ausführungskontext wird häufig verwendet, um Ressourcen oder Verbindungszeichenfolgen bedingt hinzuzufügen, die auf vorhandene Ressourcen verweisen. Betrachten Sie das folgende Beispiel, das das bedingte Hinzufügen von Redis oder einer Verbindungszeichenfolge basierend auf dem Ausführungskontext veranschaulicht:

var builder = DistributedApplication.CreateBuilder(args);

var redis = builder.ExecutionContext.IsRunMode
    ? builder.AddRedis("redis")
    : builder.AddConnectionString("redis");

builder.AddProject<Projects.WebApplication>("api")
       .WithReference(redis);

builder.Build().Run();

Im vorherigen Code:

  • Wenn der App-Host im "Ausführen"-Modus läuft, wird eine Redis Containerressource hinzugefügt.
  • Wenn der App-Host im "Publish-Modus" ausgeführt wird, wird eine Verbindungszeichenfolge hinzugefügt.

Diese Logik kann ganz einfach umgekehrt werden, um eine Verbindung mit einer vorhandenen Redis-Ressource herzustellen, wenn Sie lokal ausgeführt werden, und eine neue Redis-Ressource zu erstellen, wenn Sie veröffentlichen.

Wichtig

.NET .NET Aspire stellt allgemeine APIs bereit, um die Modalität von Ressourcen-Generatoren zu steuern, sodass Ressourcen sich je nach Ausführungsmodus unterschiedlich verhalten können. Die Fluent-APIs werden mit RunAs* und PublishAs*vorangestellt. Die RunAs* APIs beeinflussen das Verhalten der lokalen Entwicklung (oder des Ausführungsmodus), während die PublishAs* APIs die Veröffentlichung der Ressource beeinflussen.

Siehe auch