Seit K2 2.9.3 startet aspire run die ganze Kladde. Seitdem ist der AppHost Stück für Stück gewachsen: Azure SQL statt SQL Server in 3.2.5, Azurite in 3.6.3, der Service-Bus-Emulator in 3.5.2, ein Thema in 3.5.3, der Abruf als eigene Ressource in 3.5.7. Jede Lektion hat ein paar Zeilen dazugeschrieben, und jede hat für sich gestimmt. Als Ganzes hat ihn niemand mehr gelesen.

Dieses Modul nimmt Aspire ernst als das, was es für die Kladde geworden ist: die eine Stelle, an der beschrieben steht, woraus die Anwendung besteht, wie die Teile zusammenhängen, wie man sie testet und wie sie ausgeliefert wird.

Lektion Was entsteht h
3.14.1 Das App-Modell ein aufgeräumter AppHost mit einem Parameter und einem eigenen Befehl im Dashboard 3
3.14.2 Integrationen: Hosting und Client Emulatoren lokal, Azure beim Ausrollen, eine eigene Integration für den TED-Stub 3
3.14.3 Dashboard und Service Defaults angepasste Service Defaults, die kein POST wiederholen, mit Test 3
3.14.4 Testen mit Aspire ein Test „Buchung bis Benachrichtigung“ gegen den gestarteten AppHost, in der Pipeline 3
3.14.5 Ausliefern: azd, aspire publish, aspire deploy die Entscheidung zum Auslieferungsweg 2

Das Modul arbeitet mit Aspire 13.6.5 (Pakete, SDK und CLI). Die Kladde hat seit K2 13.6.4; heben Sie alle Aspire.*-Pakete, das SDK in der Projektdatei des AppHost (Aspire.AppHost.Sdk/13.6.5) und die CLI (dotnet tool update --global Aspire.Cli --version 13.6.5) gemeinsam an, in einem Pull Request. Gemischte Versionen bauen oft trotzdem, aber dann prüfen Ihre Tests eine Zusammenstellung, die so niemand ausgeliefert hat.

Ein Modell, kein Startskript

AppHost.cs sieht aus wie ein Programm, das Dinge startet. Das täuscht. Jede Zeile mit Add… legt nur eine Ressource in ein Modell, jede Zeile mit With… oder WaitFor… hängt ihr eine Angabe an, im Code von Aspire eine Annotation. Gestartet wird erst bei builder.Build().Run(), und zwar nicht in der Reihenfolge der Zeilen, sondern in der, die sich aus den Abhängigkeiten ergibt.

Die Ressourcen der Kladde gehören zu wenigen Arten:

Art Beispiel in der Kladde was Aspire lokal tut
Projekt web, worker, migrations, import baut das Projekt und startet es mit dotnet
Container sql, die Emulatoren startet ein Image in Docker oder Podman
Azure-Ressource sql, storage, messaging in Azure ein Dienst; lokal ein Container, wenn RunAsContainer oder RunAsEmulator es sagt
Kind-Ressource kladde (Datenbank), tender-import (Warteschlange), tenders-raw (Blob-Container) gehört zu ihrer Elternressource und lebt mit ihr
Parameter ted-cpv (neu in dieser Lektion) liest einen Wert aus der Konfiguration oder fragt danach

Das Dashboard zeigt dieses Modell auf der Seite Resources, als Tabelle oder als Graph. Dieselbe Liste liefert die CLI. Mit aspire describe bekommen Sie sie als Tabelle; die Fassung mit --format json lässt sich in PowerShell weiterverarbeiten. Die erste Zeile der Ausgabe ist eine Meldung der CLI, deshalb beginnt das JSON erst beim ersten {:

PowerShell
$json = aspire describe --format json | Out-String
($json.Substring($json.IndexOf('{')) | ConvertFrom-Json).resources | Sort-Object displayName | Format-Table displayName, resourceType, state, healthStatus

So sieht das für den aufgeräumten AppHost am Ende dieser Lektion aus:

displayName     resourceType                        state      healthStatus
-----------     ------------                        -----      ------------
assessment      AzureServiceBusSubscriptionResource Running    Healthy
blobs           AzureBlobStorageResource            Running    Healthy
contact-import  AzureServiceBusQueueResource        Running    Healthy
import          Project                             NotStarted 
kladde          SqlServerDatabaseResource           Running    Healthy
messaging       AzureServiceBusResource             Running    Healthy
messaging-mssql Container                           Running    Healthy
migrations      Project                             Finished   
notification    AzureServiceBusSubscriptionResource Running    Healthy
offers          AzureBlobStorageContainerResource   Running    Healthy
sql             Container                           Running    Healthy
storage         AzureStorageResource                Running    Healthy
ted-cpv         Parameter                           Running    Healthy
tender-events   AzureServiceBusTopicResource        Running    Healthy
tender-import   AzureServiceBusQueueResource        Running    Healthy
tenders-raw     AzureBlobStorageContainerResource   Running    Healthy
web             Project                             Running    Healthy
worker          Project                             Running    Healthy

Drei Dinge fallen auf. messaging-mssql steht in keiner Zeile des AppHost: Der Service-Bus-Emulator braucht einen SQL Server als Speicher (3.5.2), und RunAsEmulator legt ihn als eigene Ressource an. import ist NotStarted, weil WithExplicitStart aus 3.5.7 sagt, dass er nur auf Knopfdruck läuft. Und cae, die Container-Apps-Umgebung aus 3.2.5, fehlt ganz: Sie gibt es nur beim Veröffentlichen.