översikt över .NET.NET Aspire orkestrering
.NET .NET Aspire tillhandahåller API:er för att uttrycka resurser och beroenden i ditt distribuerade program. Förutom dessa API:er det finns verktyg som möjliggör flera övertygande scenarier. Orchestrator är avsedd för lokal utveckling ändamål och stöds inte i produktionsmiljöer.
Innan du fortsätter bör du överväga några vanliga termer som används i .NET.NET Aspire:
- App model: En samling resurser som utgör ditt distribuerade program (DistributedApplication), som definierats i Aspire.Hosting.ApplicationModel namnrymd. En mer formell definition finns i Definiera appmodellen.
- App host/Orchestrator project: Det .NET projekt som samordnar appmodellen, med namnet med *. AppHost suffix (enligt konvention).
- Resurs: En resurs är en beroende del av ett program, till exempel ett .NET projekt, container, körbar fil, databas, cache eller molntjänst. Den representerar alla delar av programmet som kan hanteras eller refereras till.
- Integration: En integrering är ett NuGet-paket för antingen appvärd som modellerar en resurs eller ett paket som konfigurerar en client för användning i en app som förbrukar. Mer information finns i översikten över .NET.NET Aspire integreringar.
- Referens: En referens definierar en anslutning mellan resurser, uttryckt som ett beroende med hjälp av WithReference-API:et. Mer information finns i Referensresurser eller Referera till befintliga resurser.
Obs
.NET .NET Aspireorkestrering är utformad för att förbättra din lokala utveckling upplevelse genom att förenkla hanteringen av konfigurationen och sammankopplingarna för din molnbaserade app. Även om det är ett ovärderligt verktyg för utveckling är det inte avsett att ersätta produktionsmiljösystem som Kubernetes, som är särskilt utformade för att fungera i det sammanhanget.
Definiera appmodellen
.NET .NET Aspire ger dig möjlighet att sömlöst skapa, etablera, distribuera, konfigurera, testa, köra och observera dina distribuerade program. Alla dessa funktioner uppnås genom användning av en appmodell som beskriver resurserna i din .NET.NET Aspire lösning och deras relationer. Dessa resurser omfattar projekt, körbara filer, containrar och externa tjänster och molnresurser som din app är beroende av. I varje .NET.NET Aspire-lösning finns ett utsett appvärdprojekt, där appmodellen definieras exakt genom att använda metoder tillgängliga på IDistributedApplicationBuilder. Den här byggaren hämtas genom att anropa DistributedApplication.CreateBuilder.
// 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();
Appvärdprojekt
Appvärdprojektet hanterar körningen av alla projekt som ingår i .NET.NET Aspire projektet. Med andra ord ansvarar den för att orkestrera alla appar i appmodellen. Själva projektet är ett .NET körbart projekt som refererar till 📦Aspire.Hosting.AppHost NuGet-paket, ställer in egenskapen IsAspireHost
till true
, och refererar till .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>
Följande kod beskriver en appvärd Program
med två projektreferenser och en 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();
Föregående kod:
- Skapar en ny appmodellbyggare med hjälp av metoden CreateBuilder.
- Lägger till en Redis
cache
resurs med namnet "cache" med hjälp av metoden AddRedis. - Lägger till en projektresurs med namnet "apiservice" med hjälp av metoden AddProject.
- Lägger till en projektresurs med namnet "webfrontend" med hjälp av metoden AddProject.
- Anger att projektet har externa HTTP-slutpunkter med hjälp av metoden WithExternalHttpEndpoints.
- Lägger till en referens till resursen
cache
och väntar tills den är klar med hjälp av metoderna WithReference och WaitFor. - Lägger till en referens till resursen
apiservice
och väntar tills den är klar med hjälp av metoderna WithReference och WaitFor.
- Skapar och kör appmodellen med hjälp av metoderna Build och Run.
Exempelkoden använder .NET AspireRedis för hostingintegration.
Tänk på följande diagram för att visualisera relationen mellan appvärdprojektet och de resurser som beskrivs:
Varje resurs måste ha ett unikt namn. Det här diagrammet visar varje resurs och relationerna mellan dem. Containerresursen heter "cache" och projektresurserna heter "apiservice" och "webfrontend". Webbklientdelsprojektet refererar till cache- och API-tjänstprojekten. När du uttrycker referenser på det här sättet säger webbklientdelsprojektet att det beror på dessa två resurser, "cache" respektive "apiservice".
Inbyggda resurstyper
.NET .NET Aspire projekt består av en uppsättning resurser. De primära basresurstyperna i 📦Aspire. Hosting.AppHost NuGet-paketet beskrivs i följande tabell:
Metod | Resurstyp | Beskrivning |
---|---|---|
AddProject | ProjectResource | Ett .NET projekt, till exempel en ASP.NET Core webbapp. |
AddContainer | ContainerResource | En containeravbildning, till exempel en Docker avbildning. |
AddExecutable | ExecutableResource | En körbar fil, till exempel en Node.js app. |
AddParameter | ParameterResource | En parameterresurs som kan användas för att uttrycka externa parametrar. |
Projektresurser representerar .NET projekt som ingår i appmodellen. När du lägger till en projektreferens till appvärdprojektet genererar .NET.NET Aspire SDK en typ i Projects
namnområdet för varje refererat projekt. Mer information finns i .NET.NET Aspire SDK: Projektreferenser.
Om du vill lägga till ett projekt i appmodellen använder du metoden AddProject:
var builder = DistributedApplication.CreateBuilder(args);
// Adds the project "apiservice" of type "Projects.AspireApp_ApiService".
var apiservice = builder.AddProject<Projects.AspireApp_ApiService>("apiservice");
Projekt kan replikeras och skalas ut genom att lägga till flera instanser av samma projekt i appmodellen. Om du vill konfigurera repliker använder du metoden WithReplicas:
var builder = DistributedApplication.CreateBuilder(args);
// Adds the project "apiservice" of type "Projects.AspireApp_ApiService".
var apiservice = builder.AddProject<Projects.AspireApp_ApiService>("apiservice")
.WithReplicas(3);
Föregående kod lägger till tre repliker av projektresursen "apiservice" i appmodellen. För mer information, se .NET.NET Aspire kontrollpanel: Resursrepliker.
Referensresurser
En referens representerar ett beroende mellan resurser. Du kan till exempel förmodligen föreställa dig ett scenario där en webbklientdel är beroende av en Redis cache. Överväg följande exempelprogramvärd Program
C#-kod:
var builder = DistributedApplication.CreateBuilder(args);
var cache = builder.AddRedis("cache");
builder.AddProject<Projects.AspireApp_Web>("webfrontend")
.WithReference(cache);
Projektresursen "webfrontend" använder WithReference för att lägga till ett beroende av containerresursen "cache". Dessa beroenden kan representera anslutningssträngar eller tjänstidentifiering information. I föregående exempel matas en miljövariabel in i resursen "webfronend" med namnet ConnectionStrings__cache
. Den här miljövariabeln innehåller en anslutningssträng som webfrontend
använder för att ansluta till Redis via .NET AspireRedis integration, till exempel ConnectionStrings__cache="localhost:62354"
.
Väntar på resurser
I vissa fall kanske du vill vänta tills en resurs är klar innan du startar en annan resurs. Du kanske till exempel vill vänta tills en databas är klar innan du startar ett API som är beroende av den. Använd metoden WaitFor för att uttrycka det här beroendet:
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);
I föregående kod väntar projektresursen "apiservice" på att databasresursen "postgresdb" ska ange KnownResourceStates.Running. Exempelkoden visar .NET AspirePostgreSQL integrering, men samma mönster kan tillämpas på andra resurser.
Andra fall kan kräva att man väntar tills en resurs körs klart, antingen KnownResourceStates.Exited eller KnownResourceStates.Finished, innan den beroende resursen kan börja. För att vänta tills en resurs har körts klart, använd metoden WaitForCompletion:
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);
I den föregående koden väntar projektresursen "apiservice" på att projektresursen "migrering" ska köras klart innan den startar. Projektresursen "migrering" väntar på att databasresursen "postgresdb" ska ange KnownResourceStates.Running. Detta kan vara användbart i scenarier där du till exempel vill köra en databasmigrering innan du startar API-tjänsten.
API:er för att lägga till och uttrycka resurser
.NET .NET Aspire som är värd för integreringar och client integreringar levereras båda som NuGet-paket, men de har olika syften. Även om client integrationer tillhandahåller client bibliotekskonfiguration för användning av appar utanför applikationsvärdens omfång, värdintegrationer tillhandahåller API:er för att uttrycka resurser och beroenden i applikationsvärden. Mer information finns i översikten över .NET.NET Aspire integreringar: Integrationsansvar.
Expresscontainerresurser
För att uttrycka en ContainerResource lägger du till den i en IDistributedApplicationBuilder-instans genom att anropa metoden AddContainer:
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");
Mer information finns i GPU-stöd i Docker Desktop.
Föregående kod lägger till en containerresurs med namnet "ollama" med avbildningen ollama/ollama
. Containerresursen konfigureras med flera bindningsmonteringar, en namngiven HTTP-slutpunkt, en startpunkt som matchar Unix shell-skript och containerkörningsargument med metoden WithContainerRuntimeArgs.
Anpassa containerresurser
Alla ContainerResource underklasser kan anpassas för att uppfylla dina specifika krav. Detta kan vara användbart när du använder en hostingintegration som modellerar en containerresurs, men som dock kräver modifieringar. När du har en IResourceBuilder<ContainerResource>
kan du länka anrop till någon av de tillgängliga API:erna för att ändra containerresursen.
.NET
.NET Aspire containerresurser pekar vanligtvis på fästa taggar, men du kanske vill använda taggen latest
i stället.
Tänk dig ett scenario där du använder .NET AspireRedis integrationför att hjälpa till att illustrera detta. Om Redis-integreringen förlitar sig på taggen 7.4
och du vill använda taggen latest
i stället kan du länka ett anrop till WithImageTag-API:et:
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.
Mer information och ytterligare API:er finns i ContainerResourceBuilderExtensions.
Livscykel för containerresurser
När appvärden körs används ContainerResource för att avgöra vilken containerbild som ska skapas och startas. Under motorhuven kör .NET Aspire containern med den definierade containeravbilden genom att delegera anrop till en lämplig OCI-kompatibel container-runtime, antingen Docker eller Podman. Följande kommandon används:
Först skapas containern med hjälp av kommandot docker container create
. Sedan startas containern med kommandot docker container start
.
- docker container skapa: Skapar en ny container från den angivna avbildningen utan att starta den.
- docker container start: Starta en eller flera stoppade containrar.
Dessa kommandon används i stället för docker run
för att hantera anslutna containernätverk, volymer och portar. Om du anropar dessa kommandon i den här ordningen kan alla IP-adresser (nätverkskonfiguration) redan finnas vid den första starten.
Utöver basresurstyperna ProjectResource, ContainerResourceoch ExecutableResource, .NET.NET Aspire tillhandahåller tilläggsmetoder för att lägga till vanliga resurser i din appmodell. För mer information, se Hostingintegrationer.
Livslängd för containerresurser
Som standard använder containerresurser session containerns livslängd. Det innebär att varje gång appvärdprocessen startas skapas och startas containern. När appvärden stoppas, stoppas containern och tas bort. Containerresurser kan välja en beständig livslängd för att undvika onödiga omstarter och bevara containertillståndet. För att uppnå detta kedjar du ett anrop till ContainerResourceBuilderExtensions.WithLifetime-API:et och skickar ContainerLifetime.Persistent:
var builder = DistributedApplication.CreateBuilder(args);
var ollama = builder.AddContainer("ollama", "ollama/ollama")
.WithLifetime(ContainerLifetime.Persistent);
Föregående kod lägger till en containerresurs med namnet "ollama" med avbildningen "ollama/ollama" och en beständig livslängd.
Anslutningssträng och slutpunktsreferenser
Det är vanligt att uttrycka beroenden mellan projektresurser. Tänk på följande exempelkod:
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);
Referenser från projekt till projekt hanteras på ett annat sätt än resurser som har väldefinierade anslutningssträngar. I stället för att anslutningssträngen matas in i resursen "webfrontend" matas miljövariabler som stöd för tjänstidentifiering in.
Metod | Miljövariabel |
---|---|
WithReference(cache) |
ConnectionStrings__cache="localhost:62354" |
WithReference(apiservice) |
services__apiservice__http__0="http://localhost:5455" services__apiservice__https__0="https://localhost:7356" |
Om du lägger till en referens till projektet "apiservice" läggs miljövariabler för tjänstidentifiering till i klientdelen. Det beror på att kommunikation mellan projekt vanligtvis sker via HTTP/gRPC. För mer information, se .NET.NET Aspire upptäckt av tjänster.
Om du vill hämta specifika slutpunkter från en ContainerResource eller en ExecutableResourceanvänder du något av följande slutpunkts-API:er:
Anropa sedan GetEndpoint-API:et för att hämta slutpunkten som kan användas för att referera till slutpunkten i metoden WithReference
:
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);
Metod | Miljövariabel |
---|---|
WithReference(endpoint) |
services__myapp__endpoint__0=https://localhost:9043 |
Parametern port
är porten som containern lyssnar på. Mer information om containerportar finns i Containerportar. Mer information om tjänstidentifiering finns i .NET.NET Aspire tjänstidentifiering.
Miljövariabelformat för tjänstslutpunktsmiljö
I föregående avsnitt används metoden WithReference för att uttrycka beroenden mellan resurser. När tjänstslutpunkter resulterar i att miljövariabler matas in i den beroende resursen kanske formatet inte är uppenbart. Det här avsnittet innehåller information om det här formatet.
När en resurs är beroende av en annan resurs infogar appens värd miljövariabler i den beroende resursen. Dessa miljövariabler konfigurerar den beroende resursen för att ansluta till den resurs som den är beroende av. Formatet för miljövariablerna är specifikt för .NET.NET Aspire och uttrycker tjänstslutpunkter på ett sätt som är kompatibelt med Service Discovery.
Namn på tjänstslutpunktsmiljövariabler prefix med services__
(dubbelt understreck), sedan tjänstnamnet, slutpunktsnamnet och slutligen indexet. Indexet stöder flera slutpunkter för en enda tjänst, från och med 0
för den första slutpunkten och ökar för varje slutpunkt.
Överväg följande miljövariabelexempel:
services__apiservice__http__0
Den föregående miljövariabeln uttrycker den första HTTP-slutpunkten för apiservice
-tjänsten. Värdet för miljövariabeln är URL:en för tjänstslutpunkten. En namngiven slutpunkt kan uttryckas på följande sätt:
services__apiservice__myendpoint__0
I föregående exempel har apiservice
-tjänsten en namngiven slutpunkt med namnet myendpoint
. Värdet för miljövariabeln är URL:en för tjänstslutpunkten.
Referera till befintliga resurser
Vissa situationer garanterar att du refererar till en befintlig resurs, kanske en som distribueras till en molnleverantör. Du kanske till exempel vill referera till en Azure databas. I det här fallet förlitar du dig på körningskontexten för att dynamiskt avgöra om appvärden körs i "körningsläge" eller "publicera"-läge. Om du kör lokalt och vill förlita dig på en molnresurs kan du använda egenskapen IsRunMode
för att villkorligt lägga till referensen. Du kan välja att i stället skapa resursen i publiceringsläge. Vissa värdintegreringar stöder att tillhandahålla en anslutningssträng direkt som kan användas för att referera till en befintlig resurs.
På samma sätt kan det finnas användningsfall där du vill integrera .NET.NET Aspire i en befintlig lösning. En vanlig metod är att lägga till .NET.NET Aspire app-värdprojektet i en befintlig lösning. I appvärden uttrycker du beroenden genom att lägga till projektreferenser till appvärden och skapa appmodellen. Ett projekt kan till exempel vara beroende av ett annat. Dessa beroenden uttrycks med hjälp av metoden WithReference. För mer information, se Lägg till .NET Aspire i en befintlig .NET-app.
Applikationsvärdens livscykler
Den .NET.NET Aspire-appvärden exponerar flera livscykler som du kan ansluta till genom att implementera IDistributedApplicationLifecycleHook-gränssnittet. Följande livscykelmetoder är tillgängliga:
Beställning | Metod | Beskrivning |
---|---|---|
1 | BeforeStartAsync | Körs innan det distribuerade programmet startar. |
2 | AfterEndpointsAllocatedAsync | Körs när orkestratorn allokerar slutpunkter för resurser i programmodellen. |
3 | AfterResourcesCreatedAsync | Körs efter att resursen har skapats av orkestreraren. |
Även om appvärden tillhandahåller livscykelkrokar kanske du vill registrera anpassade händelser. Mer information finns i Eventing i .NET.NET Aspire.
Registrera en livscykelkrok
För att registrera en livscykelkrok, implementera IDistributedApplicationLifecycleHook-gränssnittet och registrera kroken med appens värd med hjälp av AddLifecycleHook API:et.
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;
}
}
Föregående kod:
- Implementerar IDistributedApplicationLifecycleHook-gränssnittet som en
LifecycleLogger
. - Registrerar livscykelkroken med applikationsvärden med hjälp av AddLifecycleHook-API:et.
- Loggar ett meddelande för alla händelser.
När den här appvärden körs körs livscykelkroken för varje händelse. Följande utdata genereras:
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.
Det bästa sättet att ansluta till appens värdlivscykel är att använda händelse-API:et. Mer information finns i Eventing i .NET.NET Aspire.
Körningskontext
IDistributedApplicationBuilder exponerar en exekveringskontext (DistributedApplicationExecutionContext), som innehåller information om den aktuella exekveringen av applikationsvärden. Den här kontexten kan användas för att utvärdera om appvärden körs som "kör"-läge eller som en del av en publiceringsåtgärd. Tänk på följande egenskaper:
-
IsRunMode: Returnerar
true
om den aktuella åtgärden körs. -
IsPublishMode: Returnerar
true
om den aktuella åtgärden är publicering.
Den här informationen kan vara användbar när du vill köra kod villkorligt baserat på den aktuella åtgärden. Tänk dig följande exempel som visar hur du använder egenskapen IsRunMode
. I det här fallet används en tilläggsmetod för att generera ett stabilt nodnamn för RabbitMQ för lokala utvecklingskörningar.
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;
}
Körningskontexten används ofta för att villkorligt lägga till resurser eller anslutningssträngar som pekar på befintliga resurser. Tänk dig följande exempel som visar hur du villkorligt lägger till Redis eller en anslutningssträng baserat på körningskontexten:
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();
I föregående kod:
- Om appvärden körs i "kör"-läge, läggs en containerresurs av typen Redis till.
- Om värdprogrammet körs i "publiceringsläge" läggs en anslutningssträng till.
Den här logiken kan enkelt inverteras för att ansluta till en befintlig Redis resurs när du kör lokalt och skapa en ny Redis resurs när du publicerar.
Viktig
.NET
.NET Aspire tillhandahåller vanliga API:er för att styra resursskaparnas modalitet, så att resurser kan bete sig annorlunda baserat på körningsläget. De flytande API:erna är prefixade med RunAs*
och PublishAs*
. De RunAs*
API:erna påverkar beteendet för lokal utveckling (eller körningsläge), medan PublishAs*
API:er påverkar publiceringen av resursen.
Se även
.NET Aspire