Claude Skill

dotnet-aspire

Build, upgrade, and operate .NET Aspire application hosts with current CLI, AppHost, ServiceDefaults, integrations, dashboard, testing, and Azure deployment patterns for distributed apps.

LLM Mart · 0 points · 0 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download postpartum-genushyacinthus29-dotnet-skills-skills_dotnet-aspire-bfa4ebd.zip · 17 KB
Part of postpartum-genushyacinthus29/dotnet-skills — 80 skills

Install

skills CLI npx skills add https://github.com/Postpartum-genushyacinthus29/dotnet-skills/tree/main/skills/dotnet-aspire
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install postpartum-genushyacinthus29-dotnet-skills@llmmart
Git git clone https://github.com/Postpartum-genushyacinthus29/dotnet-skills.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole postpartum-genushyacinthus29/dotnet-skills collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

.NET Aspire

Trigger On

  • Aspire.AppHost.Sdk, Aspire.Hosting.*, DistributedApplication.CreateBuilder, WithReference, WaitFor, AddProject, AddRedis, AddPostgres, aspire run, aspire init, aspire add, or aspire update
  • Aspire.Hosting.Testing, DistributedApplicationTestingBuilder, or a test harness that mixes an Aspire AppHost with WebApplicationFactory
  • orchestrating multiple services and resources with an AppHost for local development or cloud deployment
  • setting up ServiceDefaults, service discovery, OpenTelemetry, health checks, or the Aspire Dashboard
  • choosing between official first-party Aspire integrations and CommunityToolkit/Aspire
  • upgrading older 8.x or 9.x Aspire solutions to the current CLI and AppHost SDK model
  • wiring polyglot services into an Aspire topology, especially when Go, Java, Python, or extra dev-time tools enter the picture

Workflow

  1. Classify the task first: new AppHost creation, existing-solution enlistment, integration wiring, testing and observability, deployment, or version upgrade.
  2. Prefer the current Aspire toolchain. For greenfield or modernized work, use the Aspire CLI and current AppHost SDK instead of writing new guidance around the deprecated legacy workload.
  3. Treat 13.1.x patches as servicing updates, not a new app model. Keep the Aspire CLI, Aspire.AppHost.Sdk, and closely coupled hosting or testing packages on the same patch line, then rerun the AppHost and deployment checks after aspire update.
  4. Keep the AppHost code-first and topology-focused. Model services, resources, dependencies, endpoints, lifetimes, and parameters there; keep business logic out.
  5. Keep ServiceDefaults narrow. It exists for telemetry, health checks, resilience, and service discovery, not shared domain models or general utility code.
  6. Prefer official first-party Aspire integrations when they cover the requirement. Use CommunityToolkit/Aspire only when the capability gap is real: unsupported language hosts, extra dev infrastructure, or extension packages the official project does not provide.
  7. Validate the whole distributed system, not one project in isolation. Local success means the AppHost starts cleanly, dependencies resolve through WithReference, the dashboard shows the expected resource graph, and end-to-end tests can exercise the topology.
  8. For integration tests, keep one shared AppHost fixture per test session. Use Aspire.Hosting.Testing to boot the distributed app, create HttpClient or SignalR clients from the AppHost, and layer WebApplicationFactory on top only when tests need direct Host DI, grains, or runtime services.
  9. When publishing, switch from local containers or emulators to managed resources deliberately and verify which services truly need external endpoints.

Architecture

flowchart LR
  A["Distributed-app task"] --> B{"Need code-first orchestration?"}
  B -->|No| C["Stay in service-level skills such as ASP.NET Core, Worker, or Orleans"]
  B -->|Yes| D["Create or update the AppHost"]
  D --> E["Model resources and services with `WithReference` and `WaitFor`"]
  E --> F{"Official Aspire integration exists?"}
  F -->|Yes| G["Use first-party Aspire integration"]
  F -->|No or gap remains| H["Evaluate `CommunityToolkit/Aspire`"]
  G --> I["Apply `ServiceDefaults`, dashboard, and tests"]
  H --> I
  I --> J{"Publishing now?"}
  J -->|No| K["Run locally with `aspire run` or the AppHost project"]
  J -->|Yes| L["Choose `azd`, App Service, or the CLI deploy/publish pipeline"]

Current Guidance

  • AppHost shape: prefer current SDK-style AppHost projects using Aspire.AppHost.Sdk/<version> or a file-based AppHost when that repo intentionally uses the single-file model. Recognize both as valid current patterns.
  • CLI entry points: use aspire new for starter projects, aspire init to add Aspire support to an existing solution or create a single-file AppHost, aspire add to add integrations or starter pieces, aspire run for local orchestration, aspire deploy for the current CLI deploy pipeline, and aspire update for version-aware upgrades. aspire publish still exists for explicit artifact-generation flows and remains preview-sensitive.
  • Patch posture: Aspire 13.1.3 is a servicing release. Treat it as a patch-line refresh for the current CLI-first workflow, not a new topology model; align package versions, rerun aspire update, then revalidate local orchestration and the chosen deployment path.
  • App model wiring: use WithReference(...) for dependency and configuration flow, and WaitFor(...) for startup ordering. Use WithExternalHttpEndpoints() only when the resource truly needs an externally reachable endpoint for the chosen runtime or publish target.
  • ServiceDefaults boundaries: AddServiceDefaults() should stay focused on OpenTelemetry, health endpoints, service discovery, HttpClient resilience, and related cross-cutting infrastructure.
  • Testing model: prefer Aspire closed-box testing when you need to run the distributed application as a system. Use DistributedApplicationTestingBuilder plus a shared fixture for AppHost lifecycle, App.CreateHttpClient(...) for resource-bound clients, and a WebApplicationFactory<TEntryPoint> wrapper only when the test must resolve DI services or in-process runtime state from the hosted app. For UI flows, initialize Playwright once in the shared fixture, create a fresh browser context per test, and capture failure artifacts.
  • Dashboard usage: treat the Aspire Dashboard as the development observability surface. It is valuable in AppHost runs and standalone OTLP scenarios, but it is not a production monitoring replacement.
  • Upgrade posture: older 8.x or 9.x solutions need explicit migration work. Current guidance favors the Aspire CLI upgrade path and the newer AppHost SDK structure on .NET 10.

Selection Rules

  • Use first-party Aspire when the package and docs exist for the resource or platform, especially for core .NET, Azure, cache, database, messaging, and standard local-container flows.
  • Use CommunityToolkit/Aspire when you need polyglot app hosts beyond official coverage, extra dev-time tools around a resource, or community-maintained integrations such as SQLite, Java, Go, PowerShell, k6, MailPit, MinIO, or Meilisearch.
  • Prefer the smallest surface that solves the problem. Do not add a broad toolkit extension pack when an existing first-party integration plus a normal library already fits.
  • Treat toolkit packages as community-supported. Verify maturity, maintenance, external container images, and security or licensing assumptions before making them part of a production baseline.

Official Sources

Anti-Patterns

  • hardcoding service URLs or connection strings instead of using WithReference
  • putting business logic, data migrations, or large configuration transforms inside the AppHost
  • turning ServiceDefaults into a dumping ground for shared models or helpers
  • adding external HTTP endpoints everywhere instead of only where runtime or publish needs them
  • defaulting to CommunityToolkit/Aspire when first-party Aspire already covers the requirement
  • assuming the dashboard or local containers automatically mean production readiness
  • treating Aspire tests as a mocking framework; they run the application as a real distributed system

Deliver

  • a version-aware Aspire architecture or upgrade direction
  • the right AppHost, ServiceDefaults, integration, and CLI workflow
  • an explicit first-party versus CommunityToolkit/Aspire package decision
  • an end-to-end validation path for local orchestration, testing, and deployment

Validate

  • the AppHost starts cleanly via aspire run or the AppHost project
  • resources and projects are modeled with explicit WithReference and WaitFor relationships where needed
  • consuming apps resolve endpoints and connection strings without hardcoded values
  • ServiceDefaults contains only cross-cutting infrastructure concerns
  • dashboard, health checks, logs, and traces reflect the expected resource graph
  • Aspire-backed integration tests reuse a shared AppHost fixture instead of booting the distributed app inside each test
  • any WebApplicationFactory layer reuses connection strings and endpoints from the AppHost instead of duplicating local config
  • testing and deployment guidance matches the chosen runtime: local AppHost, standalone dashboard, ACA/App Service, or the CLI deploy/publish pipeline

References

  • patterns.md - Current CLI-first setup flows, AppHost patterns, ServiceDefaults, testing, and upgrade checkpoints
  • testing.md - Shared AppHost fixtures, DistributedApplicationTestingBuilder, WebApplicationFactory integration, Playwright bootstrapping, and diagnostics
  • deployment.md - ACA, App Service, publish-mode, and manifest-oriented deployment guidance
  • community-toolkit.md - Practical guide to CommunityToolkit/Aspire packages, capability gaps, and selection rules
Files (dotnet-skills)
  • agents
    • dotnet-aspire-orchestrator
      • AGENT.md 3.2 KB
        ---
        name: dotnet-aspire-orchestrator
        description: Specialist orchestration agent for .NET Aspire work. Use when the problem is clearly about AppHost design, ServiceDefaults, first-party versus CommunityToolkit/Aspire integrations, dashboard and testing, `DistributedApplicationTestingBuilder`, `WebApplicationFactory` integration, or Azure deployment choices within an Aspire solution.
        tools: Read, Edit, Glob, Grep, Bash
        model: inherit
        skills:
          - dotnet-aspire
          - dotnet-aspnet-core
          - dotnet-web-api
          - dotnet-minimal-apis
          - dotnet-worker-services
          - dotnet-orleans
          - dotnet-azure-functions
          - dotnet-microsoft-extensions
        ---
        
        # .NET Aspire Orchestrator
        
        ## Role
        
        Own routing inside the Aspire surface once it is clear that the repo is already using Aspire or the task is explicitly about adding Aspire. Separate AppHost-level concerns from the implementation details of the individual services.
        
        This is a skill-scoped specialist agent. It belongs next to `dotnet-aspire` because it only makes sense inside the Aspire framework surface and should rely on the `dotnet-aspire` skill for detailed implementation guidance.
        
        ## Trigger On
        
        - `Aspire.AppHost.Sdk`, `DistributedApplication.CreateBuilder`, `WithReference`, `WaitFor`, `Aspire.Hosting.Testing`, `DistributedApplicationTestingBuilder`, `aspire new`, `aspire init`, `aspire add`, `aspire run`, or `aspire update`
        - AppHost structure, ServiceDefaults, dashboard, or testing questions inside an Aspire solution
        - tasks that mix an AppHost-backed test fixture with `WebApplicationFactory`, SignalR clients, or Playwright
        - choosing between official Aspire integrations and `CommunityToolkit/Aspire`
        - selecting a deployment path such as local AppHost, Azure Container Apps via `azd`, App Service, or the CLI deploy/publish pipeline
        
        ## Workflow
        
        1. Classify the task as create, upgrade, integration, testing and observability, or deployment.
        2. Keep AppHost topology work separate from service implementation work.
        3. Route into companion service skills when the real bottleneck is the hosted service itself rather than the orchestration layer.
        4. Keep first-party Aspire as the default and choose `CommunityToolkit/Aspire` only for a concrete capability gap.
        5. End with a validation path that proves the distributed topology works, not just a single project.
        
        ## Skill Routing
        
        - Core orchestration, AppHost, CLI, ServiceDefaults, and dashboard: `dotnet-aspire`
        - ASP.NET Core service implementation: `dotnet-aspnet-core`, `dotnet-web-api`, or `dotnet-minimal-apis`
        - Background executables and hosted workers: `dotnet-worker-services`
        - Orleans clusters inside Aspire: `dotnet-orleans`
        - Azure Functions in an Aspire topology: `dotnet-azure-functions`
        - Shared hosting, configuration, DI, and `HttpClient` defaults: `dotnet-microsoft-extensions`
        
        ## Deliver
        
        - Aspire task classification
        - recommended AppHost and package path
        - explicit first-party versus toolkit decision
        - concrete validation and deployment path
        
        ## Boundaries
        
        - Do not duplicate deep framework guidance that already belongs in `dotnet-aspire` or companion service skills.
        - Do not stay at the orchestration layer once it is obvious that the real issue is service implementation.
        - Do not recommend toolkit packages without naming the concrete gap they solve.
        
  • references
    • community-toolkit.md 6.5 KB
      # `CommunityToolkit/Aspire` Reference
      
      Use this reference when official first-party Aspire integrations do not cover the scenario or when the user explicitly asks about `CommunityToolkit/Aspire`.
      
      Last verified against:
      
      - `CommunityToolkit/Aspire` release `v13.1.1` published on `2026-01-16`
      - the current repository README package index and Microsoft Learn Community Toolkit pages
      
      ## Table of Contents
      
      - [When to use the toolkit](#when-to-use-the-toolkit)
      - [Selection rules](#selection-rules)
      - [Package families](#package-families)
      - [What not to do](#what-not-to-do)
      
      ## When to use the toolkit
      
      Reach for `CommunityToolkit/Aspire` when you need one of these:
      
      - polyglot host integrations beyond first-party Aspire coverage
      - community-maintained resource integrations that official Aspire does not provide
      - extra development-time utilities around existing resource types
      - niche infrastructure or test-tool resources that should still live in the AppHost model
      
      Do not reach for it simply because it exists. First-party Aspire remains the default for core official scenarios.
      
      ## Selection rules
      
      ### Prefer first-party Aspire when
      
      - official Aspire already has the integration you need
      - the scenario is a mainstream database, cache, Azure resource, messaging broker, or normal .NET service topology
      - the repo benefits from staying as close as possible to Microsoft-maintained docs and examples
      
      ### Prefer `CommunityToolkit/Aspire` when
      
      - you need to host non-.NET apps such as Go, Java, PowerShell, Deno, Bun, or Rust in the AppHost
      - you need SQLite-specific hosting or related EF and client wiring
      - you want extra dev-time tools such as MailPit, ngrok, k6, McpInspector, Adminer, or DbGate in the topology
      - you need community-maintained integrations such as Meilisearch, MinIO, RavenDB, SurrealDB, KurrentDB, LavinMQ, or Zitadel
      - you need extension packages around existing first-party resources, such as Redis, PostgreSQL, SQL Server, MySQL, MongoDB, Keycloak, Elasticsearch, or OpenTelemetry Collector support
      
      ## Package families
      
      The toolkit surface is large. Keep the selection practical and grouped by problem type rather than trying to memorize every package name.
      
      ### Polyglot and executable app hosting
      
      Use these when the AppHost must orchestrate non-.NET executable projects:
      
      - `CommunityToolkit.Aspire.Hosting.Golang`
      - `CommunityToolkit.Aspire.Hosting.Java`
      - `CommunityToolkit.Aspire.Hosting.Python.Extensions`
      - `CommunityToolkit.Aspire.Hosting.JavaScript.Extensions`
      - `CommunityToolkit.Aspire.Hosting.PowerShell`
      - `CommunityToolkit.Aspire.Hosting.Deno`
      - `CommunityToolkit.Aspire.Hosting.Bun`
      - `CommunityToolkit.Aspire.Hosting.Rust`
      
      These are especially important because current AppHost guidance explicitly points to toolkit integrations for Go and Java, while JavaScript has first-party coverage and Python often routes through the toolkit extension path.
      
      ### Databases, object stores, and search
      
      Use these when the missing capability is a specific backing technology:
      
      - `CommunityToolkit.Aspire.Hosting.Sqlite`
      - `CommunityToolkit.Aspire.Microsoft.Data.Sqlite`
      - `CommunityToolkit.Aspire.Microsoft.EntityFrameworkCore.Sqlite`
      - `CommunityToolkit.Aspire.Hosting.RavenDB`
      - `CommunityToolkit.Aspire.RavenDB.Client`
      - `CommunityToolkit.Aspire.Hosting.Meilisearch`
      - `CommunityToolkit.Aspire.Meilisearch`
      - `CommunityToolkit.Aspire.Hosting.Minio`
      - `CommunityToolkit.Aspire.Minio.Client`
      - `CommunityToolkit.Aspire.Hosting.KurrentDB`
      - `CommunityToolkit.Aspire.KurrentDB`
      - `CommunityToolkit.Aspire.Hosting.SurrealDb`
      - `CommunityToolkit.Aspire.SurrealDb`
      - `CommunityToolkit.Aspire.Hosting.SqlDatabaseProjects`
      
      This family is often the fastest way to keep uncommon data dependencies inside the Aspire app model instead of documenting them as external setup steps.
      
      ### Messaging, eventing, and feature flags
      
      - `CommunityToolkit.Aspire.Hosting.ActiveMQ`
      - `CommunityToolkit.Aspire.Hosting.LavinMQ`
      - `CommunityToolkit.Aspire.MassTransit.RabbitMQ`
      - `CommunityToolkit.Aspire.Hosting.Flagd`
      - `CommunityToolkit.Aspire.Hosting.GoFeatureFlag`
      - `CommunityToolkit.Aspire.GoFeatureFlag`
      - `CommunityToolkit.Aspire.Hosting.Dapr`
      - `CommunityToolkit.Aspire.Hosting.Azure.Dapr`
      - `CommunityToolkit.Aspire.Hosting.Azure.Dapr.Redis`
      
      Use this family when the distributed topology needs a real eventing, pub-sub, Dapr, or feature-flagged development story instead of a plain HTTP-only graph.
      
      ### Platform extensions around existing resources
      
      These extend or deepen the official resource story:
      
      - `CommunityToolkit.Aspire.Hosting.PostgreSQL.Extensions`
      - `CommunityToolkit.Aspire.Hosting.SqlServer.Extensions`
      - `CommunityToolkit.Aspire.Hosting.Redis.Extensions`
      - `CommunityToolkit.Aspire.Hosting.MySql.Extensions`
      - `CommunityToolkit.Aspire.Hosting.MongoDB.Extensions`
      - `CommunityToolkit.Aspire.Hosting.Elasticsearch.Extensions`
      - `CommunityToolkit.Aspire.Hosting.Keycloak.Extensions`
      - `CommunityToolkit.Aspire.Hosting.Azure.Extensions`
      - `CommunityToolkit.Aspire.Hosting.Azure.DataApiBuilder`
      - `CommunityToolkit.Aspire.Hosting.OpenTelemetryCollector`
      - `CommunityToolkit.Aspire.Hosting.Flyway`
      
      Choose these when first-party Aspire gets you most of the way there, but the real missing piece is a dev tool, extension, or advanced integration surface.
      
      ### Dev-time utilities and diagnostics
      
      - `CommunityToolkit.Aspire.Hosting.MailPit`
      - `CommunityToolkit.Aspire.Hosting.PapercutSmtp`
      - `CommunityToolkit.Aspire.Hosting.Ngrok`
      - `CommunityToolkit.Aspire.Hosting.McpInspector`
      - `CommunityToolkit.Aspire.Hosting.DbGate`
      - `CommunityToolkit.Aspire.Hosting.Adminer`
      - `CommunityToolkit.Aspire.Hosting.k6`
      - `CommunityToolkit.Aspire.Hosting.Umami`
      
      Use these to keep development-only infrastructure visible in the AppHost instead of managing them out-of-band.
      
      ### AI, file transfer, commerce, and identity
      
      - `CommunityToolkit.Aspire.Hosting.Ollama`
      - `CommunityToolkit.Aspire.OllamaSharp`
      - `CommunityToolkit.Aspire.Hosting.Sftp`
      - `CommunityToolkit.Aspire.Sftp`
      - `CommunityToolkit.Aspire.Hosting.Stripe`
      - `CommunityToolkit.Aspire.Hosting.Zitadel`
      
      These are useful when a distributed application needs more than the typical database and cache story.
      
      ## What not to do
      
      - Do not add toolkit packages just because they look interesting. Tie each choice to a concrete gap.
      - Do not present community-maintained integrations as if they were automatically equivalent to first-party Aspire support.
      - Do not assume every package family is equally mature. Verify package recency, README quality, and real maintenance activity.
      - Do not let a dev-only tool become a hidden production dependency.
      
    • deployment.md 5.4 KB
      # .NET Aspire Deployment Reference
      
      Use this reference when the question is specifically about deployment shape, publish mode, Azure Container Apps, App Service, or manifest-oriented Aspire workflows.
      
      Current docs home and CLI reference now live on `aspire.dev`. The homepage and CLI docs emphasize `aspire deploy` as the current deployment command, while `aspire publish` remains a preview-oriented artifact-generation path.
      
      ## Table of Contents
      
      - [Deployment defaults](#deployment-defaults)
      - [Azure Container Apps with `azd`](#azure-container-apps-with-azd)
      - [App Service-specific guidance](#app-service-specific-guidance)
      - [Publish-mode resource switching](#publish-mode-resource-switching)
      - [CLI deploy and preview publish flows](#cli-deploy-and-preview-publish-flows)
      - [Operational checks](#operational-checks)
      
      ## Deployment defaults
      
      Current official guidance strongly favors Azure Developer CLI for the normal Azure path.
      
      Use this ordering by default:
      
      1. Local development and debugging with `aspire run`
      2. Azure Container Apps deployment with `azd`
      3. App Service only when the hosting constraints or team standards point there
      4. The CLI deploy or publish pipeline only when you explicitly need Aspire-managed deployment steps or artifact generation outside the normal `azd` flow
      
      Avoid inventing a custom deployment path before checking whether `azd` already covers the scenario.
      
      ## Azure Container Apps with `azd`
      
      ### Recommended path
      
      ```bash
      azd init
      azd up
      ```
      
      Why this path is the default:
      
      - `azd init` detects the AppHost and generates the right Azure-facing scaffolding
      - `azd up` provisions and deploys from the distributed application model
      - the workflow aligns with the official Aspire deployment tutorials
      
      ### What `azd init` is doing
      
      In an Aspire solution, `azd init` typically:
      
      1. scans the current directory for the AppHost
      2. confirms the detected distributed application
      3. generates Azure deployment files such as `azure.yaml`
      4. creates environment-specific configuration under `.azure/`
      
      ### Post-deploy dashboard access
      
      Use:
      
      ```bash
      azd monitor
      ```
      
      This is the preferred operational follow-up when the team wants the deployed Aspire Dashboard experience instead of hunting for URLs manually.
      
      ## App Service-specific guidance
      
      App Service is valid, but it is not identical to ACA in how service-to-service traffic works.
      
      ### Add the integration
      
      The current quickstart uses the Aspire App Service hosting integration:
      
      ```bash
      aspire add azure-appservice
      ```
      
      Then model the App Service environment in the AppHost:
      
      ```csharp
      var builder = DistributedApplication.CreateBuilder(args);
      
      builder.AddAzureAppServiceEnvironment("app-service-env");
      
      var api = builder.AddProject<Projects.MyShop_Api>("api")
          .WithExternalHttpEndpoints()
          .WithHttpHealthCheck("/health");
      ```
      
      Key point:
      
      - App Service currently needs externally reachable HTTP endpoints for service-to-service communication in this hosting model
      
      Do not copy a Container Apps mental model here and assume internal-only AppHost endpoints will just work.
      
      ## Publish-mode resource switching
      
      Use publish-mode branching to move from local development resources to managed Azure services cleanly:
      
      ```csharp
      var builder = DistributedApplication.CreateBuilder(args);
      
      var database = builder.ExecutionContext.IsPublishMode
          ? builder.AddAzurePostgresFlexibleServer("db").AddDatabase("catalog")
          : builder.AddPostgres("db").AddDatabase("catalog");
      
      var cache = builder.ExecutionContext.IsPublishMode
          ? builder.AddAzureRedis("cache")
          : builder.AddRedis("cache");
      
      builder.AddProject<Projects.MyShop_Api>("api")
          .WithReference(database)
          .WithReference(cache)
          .WaitFor(database)
          .WaitFor(cache);
      ```
      
      This is the normal way to express:
      
      - local containers or emulators for dev
      - managed Azure services for publish mode
      
      Do not keep separate hand-maintained topologies unless there is a real deployment-system constraint.
      
      ## CLI deploy and preview publish flows
      
      The current Aspire CLI exposes two closely related preview-sensitive paths:
      
      - `aspire deploy` for running the deploy pipeline registered in the app model
      - `aspire publish` for explicit publish and artifact-generation scenarios
      
      Use `aspire deploy` when the task explicitly calls for:
      
      - driving the app model's deploy pipeline directly from the CLI
      - generating deploy output while letting the AppHost select and run dependent pipeline steps
      - validating a repo-specific Aspire deployment story outside `azd`
      
      Use `aspire publish` when the task explicitly calls for:
      
      - deployment artifact generation
      - manifest-oriented handoff to another toolchain
      - inspection of the publish output instead of a direct `azd` deployment
      
      Treat both flows as version-sensitive and preview-sensitive. Verify current docs and command behavior before encoding them into long-lived repo automation.
      
      ## Operational checks
      
      Before calling a deployment story "done", verify:
      
      1. The local AppHost still runs after any publish-mode branching changes.
      2. Resources that must be external are explicitly external, and resources that should remain internal are not accidentally exposed.
      3. The dashboard, traces, and health endpoints reflect the expected topology after deployment.
      4. Environment-specific parameters and secrets are injected through the AppHost model or deployment tooling rather than copy-pasted config files.
      5. The team can explain why the target is ACA, App Service, `aspire deploy`, or `aspire publish`.
      
    • patterns.md 11.2 KB
      # .NET Aspire Patterns Reference
      
      Use this reference when the task is clearly about current Aspire application-host design, CLI-first workflows, `ServiceDefaults`, testing, or upgrade checkpoints.
      
      ## Table of Contents
      
      - [CLI-first setup flows](#cli-first-setup-flows)
      - [AppHost shapes](#apphost-shapes)
      - [Current AppHost modeling patterns](#current-apphost-modeling-patterns)
      - [Dependency and configuration flow](#dependency-and-configuration-flow)
      - [ServiceDefaults boundaries](#servicedefaults-boundaries)
      - [Servicing patch posture](#servicing-patch-posture)
      - [Closed-box testing](#closed-box-testing)
      - [Upgrade checkpoints](#upgrade-checkpoints)
      - [Anti-patterns](#anti-patterns)
      
      ## CLI-first setup flows
      
      ### Create a new starter application
      
      Use the current Aspire CLI when the user wants a fresh distributed-app baseline:
      
      ```bash
      aspire new aspire-starter --name MyShop
      cd MyShop
      aspire run
      ```
      
      This gives you the modern baseline:
      
      - an AppHost for orchestration
      - a ServiceDefaults project for cross-cutting infrastructure
      - sample service projects wired into the AppHost
      - the Aspire Dashboard for local observability
      
      ### Enlist an existing solution
      
      When the repo already has working services and you want to add orchestration instead of recreating the solution:
      
      ```bash
      aspire init
      ```
      
      Use `aspire init` when you need one of these:
      
      - an AppHost added to an existing solution
      - a file-based AppHost created quickly
      - Aspire support layered onto code that already exists
      
      ### Add capabilities with the CLI
      
      Use the CLI to add official integrations or starter assets instead of hand-editing packages when the command exists:
      
      ```bash
      aspire add <integration-or-starter>
      ```
      
      Use `aspire add` when it improves repeatability, especially for:
      
      - common first-party integrations
      - starter resources that should match current Aspire conventions
      - reducing hand-written AppHost or project-file drift
      
      ## Servicing patch posture
      
      Aspire `13.1.3` is a servicing release, not a new application model. The current release notes only call out installer publishing work, so the right operational response is to keep the existing 13.1 CLI-first guidance and make patch upgrades boring and consistent.
      
      When you roll a 13.1.x patch:
      
      1. Keep the Aspire CLI and `Aspire.AppHost.Sdk` on the same patch line.
      2. Update adjacent Aspire packages that move with the AppHost, especially hosting and testing packages.
      3. Run `aspire update` before hand-editing package versions unless the repo intentionally pins them.
      4. Revalidate the AppHost start path, resource graph, dashboard, and any deployment scripts after the patch lands.
      
      Do not re-architect the AppHost just because a servicing release shipped.
      
      ## AppHost shapes
      
      Current Aspire supports two valid AppHost styles.
      
      ### Project-based AppHost
      
      Use this when the repo already uses the normal solution and project structure:
      
      ```xml
      <Project Sdk="Aspire.AppHost.Sdk/<version>">
        <PropertyGroup>
          <TargetFramework>net10.0</TargetFramework>
          <Nullable>enable</Nullable>
          <ImplicitUsings>enable</ImplicitUsings>
        </PropertyGroup>
      
        <ItemGroup>
          <ProjectReference Include="..\MyShop.Api\MyShop.Api.csproj" />
          <ProjectReference Include="..\MyShop.Web\MyShop.Web.csproj" />
        </ItemGroup>
      </Project>
      ```
      
      Prefer the SDK-style AppHost in current projects. Do not create new 13-era examples that manually model the older AppHost package layout as if it were the default.
      
      ### File-based AppHost
      
      Use this when a lightweight single-file orchestration layer is the better fit:
      
      ```csharp
      var builder = DistributedApplication.CreateBuilder(args);
      
      var postgres = builder.AddPostgres("db")
          .AddDatabase("appdata");
      
      builder.AddProject<Projects.MyShop_Api>("api")
          .WithReference(postgres)
          .WaitFor(postgres);
      
      builder.Build().Run();
      ```
      
      File-based AppHosts are useful for experimentation, smaller repos, and incremental adoption. They do not automatically include a ServiceDefaults project, so create one when the services need it.
      
      ## Current AppHost modeling patterns
      
      ### Minimal multi-service topology
      
      ```csharp
      var builder = DistributedApplication.CreateBuilder(args);
      
      var postgres = builder.AddPostgres("postgres")
          .AddDatabase("catalog")
          .WithDataVolume();
      
      var cache = builder.AddRedis("cache");
      
      var api = builder.AddProject<Projects.MyShop_Api>("api")
          .WithReference(postgres)
          .WithReference(cache)
          .WaitFor(postgres)
          .WaitFor(cache);
      
      builder.AddProject<Projects.MyShop_Web>("web")
          .WithReference(api);
      
      builder.Build().Run();
      ```
      
      What matters:
      
      - infrastructure resources are modeled explicitly
      - consuming services get their config through `WithReference(...)`
      - startup ordering is intentional through `WaitFor(...)`
      - the AppHost stays at topology level
      
      ### Persistent local resources
      
      If the slow path is repeated container bootstrap rather than code changes, keep state across local AppHost restarts:
      
      ```csharp
      var postgres = builder.AddPostgres("postgres")
          .WithDataVolume()
          .WithLifetime(ContainerLifetime.Persistent)
          .AddDatabase("catalog");
      ```
      
      Use persistence deliberately. It is helpful for realistic local development, but it can hide initialization bugs if the team forgets the difference between a cold start and a reused container.
      
      ### Publish-mode resource switching
      
      Use publish-mode branching when local development should use containers or emulators while published environments should use managed Azure resources:
      
      ```csharp
      var builder = DistributedApplication.CreateBuilder(args);
      
      var cache = builder.ExecutionContext.IsPublishMode
          ? builder.AddAzureRedis("cache")
          : builder.AddRedis("cache").WithDataVolume();
      
      var database = builder.ExecutionContext.IsPublishMode
          ? builder.AddAzurePostgresFlexibleServer("db").AddDatabase("catalog")
          : builder.AddPostgres("db").AddDatabase("catalog");
      
      builder.AddProject<Projects.MyShop_Api>("api")
          .WithReference(cache)
          .WithReference(database)
          .WaitFor(cache)
          .WaitFor(database);
      ```
      
      This pattern is better than trying to maintain separate hand-written local and cloud topologies.
      
      ## Dependency and configuration flow
      
      Official Aspire guidance treats integrations as two related but independent layers:
      
      - hosting integrations extend `IDistributedApplicationBuilder` and model resources in the AppHost
      - client integrations wire client libraries into DI, health checks, resiliency, and telemetry
      
      Use that split intentionally.
      
      ### `WithReference` is the default wiring mechanism
      
      `WithReference(...)` is the normal way to pass endpoints, connection strings, credentials, or other configuration between resources.
      
      Use it instead of:
      
      - hardcoded URLs
      - copy-pasted connection strings
      - manually synchronized environment variables
      
      ### `WaitFor` is for startup order, not configuration
      
      `WaitFor(...)` solves a different problem than `WithReference(...)`.
      
      - `WithReference(...)` injects configuration and expresses the dependency edge
      - `WaitFor(...)` delays startup until the dependency is ready or healthy
      
      Use both when the consuming service should not even begin until the dependency is available.
      
      ### Named endpoints
      
      Use named endpoints when a service exposes more than one surface:
      
      ```csharp
      var api = builder.AddProject<Projects.MyShop_Api>("api")
          .WithHttpEndpoint(port: 5001, name: "public")
          .WithHttpEndpoint(port: 5002, name: "internal");
      ```
      
      Named endpoints are useful for:
      
      - separating public versus internal traffic
      - gRPC and HTTP on the same service
      - routing test-only or admin endpoints distinctly
      
      ## ServiceDefaults boundaries
      
      The current ServiceDefaults template exists to centralize cross-cutting infrastructure, not shared business code.
      
      ### Keep it focused
      
      Good content for `ServiceDefaults`:
      
      - OpenTelemetry logging, metrics, and tracing
      - health checks
      - service discovery
      - `HttpClient` resilience defaults
      - default endpoint mapping for health endpoints
      
      Bad content for `ServiceDefaults`:
      
      - domain models
      - repository implementations
      - DTOs
      - application-specific utilities unrelated to cross-cutting infrastructure
      
      ### Typical structure
      
      ```csharp
      public static class Extensions
      {
          public static TBuilder AddServiceDefaults<TBuilder>(this TBuilder builder)
              where TBuilder : IHostApplicationBuilder
          {
              builder.ConfigureOpenTelemetry();
              builder.AddDefaultHealthChecks();
      
              builder.Services.AddServiceDiscovery();
              builder.Services.ConfigureHttpClientDefaults(http =>
              {
                  http.AddStandardResilienceHandler();
                  http.AddServiceDiscovery();
              });
      
              return builder;
          }
      }
      ```
      
      Current official guidance also keeps health endpoints and tracing filters aligned with these defaults. Do not fork this pattern casually unless the repo truly needs a custom shared-hosting baseline.
      
      ## Closed-box testing
      
      Use Aspire testing when the requirement is to exercise the distributed system as a system instead of unit-testing a single component.
      
      Prefer Aspire testing for:
      
      - end-to-end flows across multiple services
      - verifying resource startup and wiring
      - validating service discovery and real HTTP or messaging paths
      - regression tests around the AppHost topology
      
      Do not reach for Aspire testing when:
      
      - a plain xUnit or NUnit test against one class is enough
      - the service logic can be verified entirely in-process
      - the AppHost topology is irrelevant to the assertion
      
      Testing is especially important for:
      
      - ensuring `WithReference(...)` and `WaitFor(...)` match the intended runtime graph
      - catching broken resource names or renamed endpoints
      - proving a version upgrade did not silently break orchestration
      
      Load `testing.md` when the repo mixes AppHost lifecycle, `DistributedApplicationTestingBuilder`, `WebApplicationFactory`, SignalR, or Playwright instead of using Aspire as a pure black-box API harness.
      
      ## Upgrade checkpoints
      
      When modernizing older Aspire solutions, verify these points explicitly:
      
      1. The team is using the current Aspire CLI, and the upgrade path starts there.
      2. The AppHost project uses the current SDK-style layout rather than retaining older manual AppHost package wiring by inertia.
      3. The AppHost target framework is aligned with current tooling expectations for Aspire 13-era projects.
      4. The repo has removed assumptions about the old workload-based setup when those assumptions no longer apply.
      5. ServiceDefaults remains a narrow infrastructure project instead of having accumulated random shared code over time.
      
      Use:
      
      ```bash
      aspire update
      ```
      
      Pair the CLI upgrade with a review of:
      
      - AppHost project structure
      - project references
      - integration package versions
      - test coverage for the distributed topology
      - local run and dashboard behavior
      
      ## Anti-Patterns
      
      - Treating the AppHost like an ordinary application project with business logic, service implementations, or repo-specific glue.
      - Using `WithEnvironment(...)` as the first answer when `WithReference(...)` or a normal integration already models the dependency correctly.
      - Assuming `WithExternalHttpEndpoints()` belongs on every web project. It should follow runtime needs, especially publish targets such as App Service.
      - Modeling a large topology with vague resource names like `service1` and `db2`, then expecting logs and traces to remain understandable.
      - Carrying an obsolete 8.x or 9.x setup pattern into new samples or new repos without a compatibility reason.
      
    • testing.md 8 KB
      # .NET Aspire Testing Patterns
      
      Use this reference when the task is about AppHost-backed integration tests, `DistributedApplicationTestingBuilder`, mixing Aspire with `WebApplicationFactory`, Playwright UI automation, or practical diagnostics.
      
      These patterns are grounded in working production-style test harnesses used in `AIBase` and `WA.Storied.Agents`: one shared AppHost fixture per test session, optional `WebApplicationFactory` layering for Host DI/grains, and browser contexts created per test rather than per session.
      
      ## Fixture Selection
      
      ```mermaid
      flowchart LR
        A["Test needs Aspire resources"] --> B{"Needs only external surfaces?"}
        B -->|Yes| C["Shared AppHost fixture"]
        C --> D["Create HttpClient / HubConnection from DistributedApplication"]
        B -->|No, needs Host DI/grains| E["Shared AppHost fixture + WebApplicationFactory"]
        E --> F["Resolve connection strings from AppHost into test host config"]
        C --> G{"Needs UI automation?"}
        G -->|Yes| H["Initialize Playwright once, create BrowserContext per test"]
        G -->|No| I["Stay API/SignalR only"]
      ```
      
      ## Package Baseline
      
      Typical Aspire-backed integration suites need:
      
      ```xml
      <ItemGroup>
        <PackageReference Include="Aspire.Hosting.Testing" />
        <PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" />
        <PackageReference Include="Microsoft.AspNetCore.SignalR.Client" />
        <PackageReference Include="Microsoft.Playwright" />
      </ItemGroup>
      ```
      
      Add the actual test framework package separately: `TUnit`, `xunit`, or `NUnit`.
      
      ## Shared AppHost Fixture
      
      Boot the AppHost once, wait for the real resources, and hand out clients from the distributed app:
      
      ```csharp
      using Aspire.Hosting.Testing;
      
      public sealed class AspireTestFixture : IAsyncDisposable
      {
          private DistributedApplication? _app;
      
          public DistributedApplication App =>
              _app ?? throw new InvalidOperationException("App not initialized.");
      
          public string ApiUrl { get; private set; } = string.Empty;
      
          public async Task InitializeAsync()
          {
              var builder = await DistributedApplicationTestingBuilder.CreateAsync<Projects.My_AppHost>();
      
              builder.Services.AddLogging(logging =>
              {
                  logging.ClearProviders();
                  logging.AddConsole();
                  logging.SetMinimumLevel(LogLevel.Warning);
                  logging.AddFilter("Aspire.Hosting.Dcp", LogLevel.Warning);
                  logging.AddFilter("Aspire.Hosting.Backchannel", LogLevel.Critical);
              });
      
              _app = await builder.BuildAsync();
              await _app.StartAsync();
      
              using var cts = new CancellationTokenSource(TimeSpan.FromMinutes(1));
              await _app.ResourceNotifications.WaitForResourceHealthyAsync("api", cts.Token);
      
              ApiUrl = _app.CreateHttpClient("api", "http").BaseAddress?.ToString()
                  ?? throw new InvalidOperationException("API URL was not resolved.");
          }
      
          public HttpClient CreateApiClient() => App.CreateHttpClient("api", "http");
      
          public async Task DisposeAsync()
          {
              if (_app is not null)
              {
                  await _app.StopAsync();
                  await _app.DisposeAsync();
              }
          }
      }
      ```
      
      Use this shape when the test only needs the real distributed topology: API, SignalR, SSE, workers, or resource health.
      
      ## Layer `WebApplicationFactory` On Top Of Aspire Infra
      
      When the test needs Host DI services, direct `IGrainFactory` access, or in-process runtime services, reuse the AppHost infrastructure and inject its connection strings into the web host:
      
      ```csharp
      public sealed class TestApplication
          : WebApplicationFactory<HostEntryPointMarker>, IAsyncDisposable
      {
          private static readonly AspireTestFixture SharedFixture = new();
          private readonly Dictionary<string, string?> _overrides = new(StringComparer.OrdinalIgnoreCase);
      
          protected override void ConfigureWebHost(IWebHostBuilder builder)
          {
              builder.UseEnvironment(Environments.Development);
      
              builder.ConfigureAppConfiguration((_, config) =>
              {
                  config.AddInMemoryCollection(new Dictionary<string, string?>
                  {
                      ["Logging:LogLevel:Default"] = "Warning",
                      ["Logging:LogLevel:Orleans"] = "Warning",
                      ["Logging:LogLevel:Aspire"] = "Warning",
                  });
      
                  config.AddInMemoryCollection(_overrides);
              });
          }
      
          public async Task InitializeAsync()
          {
              await SharedFixture.InitializeAsync();
      
              var tables = await SharedFixture.App.GetConnectionStringAsync("tables");
              var blobs = await SharedFixture.App.GetConnectionStringAsync("blobs");
      
              _overrides["ConnectionStrings:Tables"] = tables;
              _overrides["ConnectionStrings:Blobs"] = blobs;
      
              Environment.SetEnvironmentVariable("ConnectionStrings__Tables", tables);
              Environment.SetEnvironmentVariable("ConnectionStrings__Blobs", blobs);
      
              CreateClient();
          }
      
          public new HttpClient CreateClient()
          {
              var client = base.CreateClient();
              client.Timeout = TimeSpan.FromMinutes(5);
              return client;
          }
      
          public async Task DisposeAsync()
          {
              Dispose();
              await SharedFixture.DisposeAsync();
          }
      }
      ```
      
      Rules that matter:
      
      - boot Aspire once, not per test
      - resolve connection strings and endpoints from `SharedFixture.App`, not from copied local config
      - keep `WebApplicationFactory` focused on DI/runtime access, not infrastructure provisioning
      - adapt the lifecycle surface to the active test framework: xUnit `IAsyncLifetime`, TUnit `IAsyncInitializer`, or the repo's own fixture abstraction
      
      ## Playwright In The Shared Fixture
      
      Initialize the browser once, then create a fresh browser context per test:
      
      ```csharp
      public async Task InitializePlaywrightAsync()
      {
          await InitializeAsync();
      
          var exitCode = Microsoft.Playwright.Program.Main(["install", "chromium"]);
          if (exitCode != 0)
          {
              throw new InvalidOperationException($"Playwright install failed: {exitCode}");
          }
      
          Playwright ??= await Microsoft.Playwright.Playwright.CreateAsync();
          Browser ??= await Playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions
          {
              Headless = true,
              Args =
              [
                  "--disable-dev-shm-usage",
                  "--disable-gpu",
                  "--window-size=1920,1080",
              ],
          });
      }
      
      public async Task<IBrowserContext> CreateBrowserContextAsync()
      {
          await InitializePlaywrightAsync();
      
          return await Browser!.NewContextAsync(new BrowserNewContextOptions
          {
              BaseURL = ApiUrl,
              IgnoreHTTPSErrors = true,
              ViewportSize = new ViewportSize { Width = 1920, Height = 1080 },
              ScreenSize = new ScreenSize { Width = 1920, Height = 1080 },
          });
      }
      ```
      
      Do not share pages or browser contexts across tests. Reuse the browser process, not mutable browser state.
      
      ## Diagnostics And Failure Capture
      
      Useful low-noise defaults:
      
      - `logging.ClearProviders(); logging.AddConsole();`
      - `logging.SetMinimumLevel(LogLevel.Warning);`
      - `logging.AddFilter("Aspire.Hosting.Dcp", LogLevel.Warning);`
      - `logging.AddFilter("Aspire.Hosting.Backchannel", LogLevel.Critical);`
      
      For failures:
      
      - dump server-side error logs from the shared fixture or `WebApplicationFactory` logger provider
      - capture Playwright screenshots and HTML into an `artifacts/` folder
      - include resource logs from the AppHost when a resource fails to become healthy
      
      Example pattern:
      
      ```csharp
      try
      {
          var response = await client.GetAsync("/health");
          response.EnsureSuccessStatusCode();
      }
      catch
      {
          Console.WriteLine(testApplication.GetHostLogDump(LogLevel.Error));
          throw;
      }
      ```
      
      ## Practical Rules
      
      - Use plain service-level tests when the AppHost topology does not matter.
      - Use Aspire testing when the assertion depends on real resource wiring, service discovery, health, or cross-service flows.
      - Mix Aspire with `WebApplicationFactory` only when the test needs direct access to DI, grains, or in-process runtime services.
      - Keep one shared AppHost fixture per test session and one browser context per UI test.
      - Prefer explicit resource names and explicit `WaitForResourceHealthyAsync(...)` checks so failures point to the right resource quickly.
      
  • SKILL.md 10 KB
    ---
    name: dotnet-aspire
    version: "1.3.1"
    category: "Cloud"
    description: "Build, upgrade, and operate .NET Aspire application hosts with current CLI, AppHost, ServiceDefaults, integrations, dashboard, testing, and Azure deployment patterns for distributed apps."
    compatibility: "Best for current Aspire 13-era tooling on .NET 10; use version-aware upgrade guidance for older 8.x or 9.x Aspire solutions."
    ---
    
    # .NET Aspire
    
    ## Trigger On
    
    - `Aspire.AppHost.Sdk`, `Aspire.Hosting.*`, `DistributedApplication.CreateBuilder`, `WithReference`, `WaitFor`, `AddProject`, `AddRedis`, `AddPostgres`, `aspire run`, `aspire init`, `aspire add`, or `aspire update`
    - `Aspire.Hosting.Testing`, `DistributedApplicationTestingBuilder`, or a test harness that mixes an Aspire AppHost with `WebApplicationFactory`
    - orchestrating multiple services and resources with an AppHost for local development or cloud deployment
    - setting up `ServiceDefaults`, service discovery, OpenTelemetry, health checks, or the Aspire Dashboard
    - choosing between official first-party Aspire integrations and `CommunityToolkit/Aspire`
    - upgrading older 8.x or 9.x Aspire solutions to the current CLI and AppHost SDK model
    - wiring polyglot services into an Aspire topology, especially when Go, Java, Python, or extra dev-time tools enter the picture
    
    ## Workflow
    
    1. Classify the task first: new AppHost creation, existing-solution enlistment, integration wiring, testing and observability, deployment, or version upgrade.
    2. Prefer the current Aspire toolchain. For greenfield or modernized work, use the Aspire CLI and current AppHost SDK instead of writing new guidance around the deprecated legacy workload.
    3. Treat 13.1.x patches as servicing updates, not a new app model. Keep the Aspire CLI, `Aspire.AppHost.Sdk`, and closely coupled hosting or testing packages on the same patch line, then rerun the AppHost and deployment checks after `aspire update`.
    4. Keep the AppHost code-first and topology-focused. Model services, resources, dependencies, endpoints, lifetimes, and parameters there; keep business logic out.
    5. Keep `ServiceDefaults` narrow. It exists for telemetry, health checks, resilience, and service discovery, not shared domain models or general utility code.
    6. Prefer official first-party Aspire integrations when they cover the requirement. Use `CommunityToolkit/Aspire` only when the capability gap is real: unsupported language hosts, extra dev infrastructure, or extension packages the official project does not provide.
    7. Validate the whole distributed system, not one project in isolation. Local success means the AppHost starts cleanly, dependencies resolve through `WithReference`, the dashboard shows the expected resource graph, and end-to-end tests can exercise the topology.
    8. For integration tests, keep one shared AppHost fixture per test session. Use `Aspire.Hosting.Testing` to boot the distributed app, create `HttpClient` or SignalR clients from the AppHost, and layer `WebApplicationFactory` on top only when tests need direct Host DI, grains, or runtime services.
    9. When publishing, switch from local containers or emulators to managed resources deliberately and verify which services truly need external endpoints.
    
    ## Architecture
    
    ```mermaid
    flowchart LR
      A["Distributed-app task"] --> B{"Need code-first orchestration?"}
      B -->|No| C["Stay in service-level skills such as ASP.NET Core, Worker, or Orleans"]
      B -->|Yes| D["Create or update the AppHost"]
      D --> E["Model resources and services with `WithReference` and `WaitFor`"]
      E --> F{"Official Aspire integration exists?"}
      F -->|Yes| G["Use first-party Aspire integration"]
      F -->|No or gap remains| H["Evaluate `CommunityToolkit/Aspire`"]
      G --> I["Apply `ServiceDefaults`, dashboard, and tests"]
      H --> I
      I --> J{"Publishing now?"}
      J -->|No| K["Run locally with `aspire run` or the AppHost project"]
      J -->|Yes| L["Choose `azd`, App Service, or the CLI deploy/publish pipeline"]
    ```
    
    ## Current Guidance
    
    - AppHost shape: prefer current SDK-style AppHost projects using `Aspire.AppHost.Sdk/<version>` or a file-based AppHost when that repo intentionally uses the single-file model. Recognize both as valid current patterns.
    - CLI entry points: use `aspire new` for starter projects, `aspire init` to add Aspire support to an existing solution or create a single-file AppHost, `aspire add` to add integrations or starter pieces, `aspire run` for local orchestration, `aspire deploy` for the current CLI deploy pipeline, and `aspire update` for version-aware upgrades. `aspire publish` still exists for explicit artifact-generation flows and remains preview-sensitive.
    - Patch posture: Aspire `13.1.3` is a servicing release. Treat it as a patch-line refresh for the current CLI-first workflow, not a new topology model; align package versions, rerun `aspire update`, then revalidate local orchestration and the chosen deployment path.
    - App model wiring: use `WithReference(...)` for dependency and configuration flow, and `WaitFor(...)` for startup ordering. Use `WithExternalHttpEndpoints()` only when the resource truly needs an externally reachable endpoint for the chosen runtime or publish target.
    - ServiceDefaults boundaries: `AddServiceDefaults()` should stay focused on OpenTelemetry, health endpoints, service discovery, `HttpClient` resilience, and related cross-cutting infrastructure.
    - Testing model: prefer Aspire closed-box testing when you need to run the distributed application as a system. Use `DistributedApplicationTestingBuilder` plus a shared fixture for AppHost lifecycle, `App.CreateHttpClient(...)` for resource-bound clients, and a `WebApplicationFactory<TEntryPoint>` wrapper only when the test must resolve DI services or in-process runtime state from the hosted app. For UI flows, initialize Playwright once in the shared fixture, create a fresh browser context per test, and capture failure artifacts.
    - Dashboard usage: treat the Aspire Dashboard as the development observability surface. It is valuable in AppHost runs and standalone OTLP scenarios, but it is not a production monitoring replacement.
    - Upgrade posture: older 8.x or 9.x solutions need explicit migration work. Current guidance favors the Aspire CLI upgrade path and the newer AppHost SDK structure on `.NET 10`.
    
    ## Selection Rules
    
    - Use first-party Aspire when the package and docs exist for the resource or platform, especially for core .NET, Azure, cache, database, messaging, and standard local-container flows.
    - Use `CommunityToolkit/Aspire` when you need polyglot app hosts beyond official coverage, extra dev-time tools around a resource, or community-maintained integrations such as SQLite, Java, Go, PowerShell, k6, MailPit, MinIO, or Meilisearch.
    - Prefer the smallest surface that solves the problem. Do not add a broad toolkit extension pack when an existing first-party integration plus a normal library already fits.
    - Treat toolkit packages as community-supported. Verify maturity, maintenance, external container images, and security or licensing assumptions before making them part of a production baseline.
    
    ## Official Sources
    
    - [Aspire docs home](https://aspire.dev/docs/)
    - [AppHost](https://aspire.dev/get-started/app-host/)
    - [Service defaults](https://aspire.dev/fundamentals/service-defaults/)
    - [Integrations overview](https://aspire.dev/integrations/overview/)
    - [Build your first app](https://aspire.dev/get-started/first-app/)
    - [Aspire CLI reference](https://aspire.dev/reference/cli/commands/aspire/)
    - [Upgrade Aspire](https://learn.microsoft.com/en-us/dotnet/aspire/get-started/upgrade-to-aspire-13)
    - [Testing overview](https://aspire.dev/testing/overview/)
    - [dotnet/aspire](https://github.com/dotnet/aspire)
    - [CommunityToolkit/Aspire](https://github.com/CommunityToolkit/Aspire)
    
    ## Anti-Patterns
    
    - hardcoding service URLs or connection strings instead of using `WithReference`
    - putting business logic, data migrations, or large configuration transforms inside the AppHost
    - turning `ServiceDefaults` into a dumping ground for shared models or helpers
    - adding external HTTP endpoints everywhere instead of only where runtime or publish needs them
    - defaulting to `CommunityToolkit/Aspire` when first-party Aspire already covers the requirement
    - assuming the dashboard or local containers automatically mean production readiness
    - treating Aspire tests as a mocking framework; they run the application as a real distributed system
    
    ## Deliver
    
    - a version-aware Aspire architecture or upgrade direction
    - the right AppHost, ServiceDefaults, integration, and CLI workflow
    - an explicit first-party versus `CommunityToolkit/Aspire` package decision
    - an end-to-end validation path for local orchestration, testing, and deployment
    
    ## Validate
    
    - the AppHost starts cleanly via `aspire run` or the AppHost project
    - resources and projects are modeled with explicit `WithReference` and `WaitFor` relationships where needed
    - consuming apps resolve endpoints and connection strings without hardcoded values
    - `ServiceDefaults` contains only cross-cutting infrastructure concerns
    - dashboard, health checks, logs, and traces reflect the expected resource graph
    - Aspire-backed integration tests reuse a shared AppHost fixture instead of booting the distributed app inside each test
    - any `WebApplicationFactory` layer reuses connection strings and endpoints from the AppHost instead of duplicating local config
    - testing and deployment guidance matches the chosen runtime: local AppHost, standalone dashboard, ACA/App Service, or the CLI deploy/publish pipeline
    
    ## References
    
    - [patterns.md](references/patterns.md) - Current CLI-first setup flows, AppHost patterns, `ServiceDefaults`, testing, and upgrade checkpoints
    - [testing.md](references/testing.md) - Shared AppHost fixtures, `DistributedApplicationTestingBuilder`, `WebApplicationFactory` integration, Playwright bootstrapping, and diagnostics
    - [deployment.md](references/deployment.md) - ACA, App Service, publish-mode, and manifest-oriented deployment guidance
    - [community-toolkit.md](references/community-toolkit.md) - Practical guide to `CommunityToolkit/Aspire` packages, capability gaps, and selection rules
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related