次の方法で共有


What's new in .NET.NET Aspire 9.2

📢 .NET Aspire 9.2 is the next minor version release of .NET Aspire; it supports:

  • .NET 8.0 Long Term Support (LTS)
  • .NET 9.0 Standard Term Support (STS)

If you have feedback, questions, or want to contribute to .NET.NET Aspire, collaborate with us on GitHub or join us on Discord to chat with team members.

It's important to note that .NET Aspire releases out-of-band from .NET releases. While major versions of .NET Aspire align with .NET major versions, minor versions are released more frequently. For more information on .NET and .NET Aspire version support, see:

⬆️ Upgrade to .NET.NET Aspire 9.2

重要

If you are using azd to deploy AzurePostgreSQL or AzureSQL Server, you now have to configure Azure Managed Identities. For more information, see 🛡️ Improved Managed Identity defaults.

Moving between minor releases of .NET.NET Aspire is simple:

  1. In your app host project file (that is, MyApp.AppHost.csproj), update the 📦Aspire.AppHost.Sdk NuGet package to version 9.2.0:

    <Project Sdk="Microsoft.NET.Sdk">
    
        <Sdk Name="Aspire.AppHost.Sdk" Version="9.2.0" />
    
        <PropertyGroup>
            <OutputType>Exe</OutputType>
            <TargetFramework>net9.0</TargetFramework>
    -       <IsAspireHost>true</IsAspireHost>
            <!-- Omitted for brevity -->
        </PropertyGroup>
    
        <ItemGroup>
            <PackageReference Include="Aspire.Hosting.AppHost" Version="9.2.0" />
        </ItemGroup>
    
        <!-- Omitted for brevity -->
    </Project>
    

    重要

    The IsAspireHost property is no longer required in the project file. For more information, see 🚧 Project file changes.

    For more information, see .NET.NET Aspire SDK.

  2. Check for any NuGet package updates, either using the NuGet Package Manager in Visual Studio or the Update NuGet Package command in VS Code.

  3. Update to the latest .NET.NET Aspire templates by running the following .NET command line:

    dotnet new update
    

    重要

    The dotnet new update command updates all of your templates to the latest version.

If your app host project file doesn't have the Aspire.AppHost.Sdk reference, you might still be using .NET.NET Aspire 8. To upgrade to 9.0, follow the upgrade guide.

🖥️ App host enhancements

The app host is the core of .NET.NET Aspire, providing the local hosting environment for your distributed applications. In .NET.NET Aspire 9.2, we've made several improvements to the app host:

🚧 Project file changes

The .NET.NET Aspire app host project file no longer requires the IsAspireHost property. This property was moved to the Aspire.AppHost.Sdk SDK, therefore, you can remove it from your project file. For more information, see dotnet/aspire issue #8144.

🔗 Define custom resource URLs

Resources can now define custom URLs. This makes it easier to build custom experiences for your resources. For example, you can define a custom URL for a database resource that points to the database management console. This makes it easier to access the management console directly from the dashboard, you can even give it a friendly name.

var builder = DistributedApplication.CreateBuilder(args);

var catalogDb = builder.AddPostgres("postgres")
                       .WithDataVolume()
                       .WithPgAdmin(resource =>
                       {
                           resource.WithUrlForEndpoint("http", u => u.DisplayText = "PG Admin");
                       })
                       .AddDatabase("catalogdb");

The preceding code sets the display text for the PG Admin URL to PG Admin. This makes it easier to access the management console directly from the dashboard.

For more information, see Define custom resource URLs.

🔧 Dashboard user experience improvements

.NET .NET Aspire 9.2 adds new features to the dashboard, making it a more powerful developer tool than ever. The following features were added to the dashboard in .NET.NET Aspire 9.2:

🧩 Resource graph

The resource graph is a new way to visualize the resources in your apps. It displays a graph of resources, linked by relationships. Click the 'Graph' tab on the Resources page to view the resource graph. See it in action on James's BlueSky.

For more information, see .NET.NET Aspire dashboard: Resources page.

🎨 Resource icons

We've added resource icons to the resources page. The icon color matches the resource's telemetry in structured logs and traces.

Screenshot of dashboard resource's page showing the new resource icons.

⏯️ Pause and resume telemetry

New buttons were added to the Console logs, Structured logs, Traces and Metrics pages to pause collecting telemetry. Click the pause button again to resume collecting telemetry.

This feature allows you to pause telemetry in the dashboard while continuing to interact with your app.

Screenshot of the dashboard showing the pause button.

❤️‍🩹 Metrics health warning

The dashboard now warns you when a metric exceeds the configured cardinality limit. Once exceeded, the metric no longer provides accurate information.

Screenshot of a metric with the cardinality limit warning.

🕰️ UTC Console logs option

Console logs now supports UTC timestamps. The setting is accessible via the console logs options button.

Screenshot of console logs page showing the UTC timestamps option.

🔎 Trace details search text box

We've added a search text box to trace details. Now you can quickly filter large traces to find the exact span you need. See it in action on BluSky.

🌐 HTTP-based resource command functionality

Custom resource commands now support HTTP-based functionality with the addition of the WithHttpCommand API, enabling you to define endpoints for tasks like database migrations or resets. These commands can be run directly from the .NET.NET Aspire dashboard.

Adds WithHttpCommand(), which lets you define a resource command that sends an HTTP request to your app during development. Useful for triggering endpoints like seed or reset from the dashboard.

if (builder.Environment.IsDevelopment())
{
    var resetDbKey = Guid.NewGuid().ToString();

    catalogDbApp.WithEnvironment("DatabaseResetKey", resetDbKey)
                .WithHttpCommand("/reset-db", "Reset Database",
                    commandOptions: new()
                    {
                        Description = "Reset the catalog database to its initial state. This will delete and recreate the database.",
                        ConfirmationMessage = "Are you sure you want to reset the catalog database?",
                        IconName = "DatabaseLightning",
                        PrepareRequest = requestContext =>
                        {
                            requestContext.Request.Headers.Add("Authorization", $"Key {resetDbKey}");
                            return Task.CompletedTask;
                        }
                    });
}

For more information, see Custom HTTP commands in .NET.NET Aspire.

🗂️ Connection string resource type

We've introduced a new ConnectionStringResource type that makes it easier to build dynamic connection strings without defining a separate resource type. This makes it easier to work with build dynamic parameterized connection strings.

var builder = DistributedApplication.CreateBuilder(args);

var apiKey = builder.AddParameter("apiKey");
var cs = builder.AddConnectionString("openai", 
    ReferenceExpression.Create($"Endpoint=https://api.openai.com/v1;AccessKey={apiKey};"));

var api = builder.AddProject<Projects.Api>("api")
                .WithReference(cs);

📥 Container resources can now specify an image pull policy

Container resources can now specify an ImagePullPolicy to control when the image is pulled. This is useful for resources that are updated frequently or that have a large image size. The following policies are supported:

  • Default: Default behavior (which is the same as Missing in 9.2).
  • Always: Always pull the image.
  • Missing: Ensures the image is always pulled when the container starts.
var builder = DistributedApplication.CreateBuilder(args);

var cache = builder.AddRedis("cache")
                   .WithImageTag("latest")
                   .WithImagePullPolicy(ImagePullPolicy.Always)
                   .WithRedisInsight();

The ImagePullPolicy is set to Always, which means the image will always be pulled when the resource is created. This is useful for resources that are updated frequently.

📂 New container files API

In .NET.NET Aspire 9.2, we've added a new WithContainerFiles API, a way to create files and folders inside a container at runtime by defining them in code. Under the hood, it uses docker cp / podman cp to copy the files in. Supports setting contents, permissions, and ownership—no bind mounts or temp files needed.

🤝 Integrations updates

Integrations are a key part of .NET.NET Aspire, allowing you to easily add and configure services in your app. In .NET.NET Aspire 9.2, we've made several updates to integrations:

🔐 Redis/Valkey/Garnet: Password support enabled by default

The Redis, Valkey, and Garnet containers enable password authentication by default. This is part of our goal to be secure by default—protecting development environments with sensible defaults while still making them easy to configure. Passwords can be set explicitly or generated automatically if not provided.

💾 Automatic database creation support

There's plenty of feedback and confusion around the AddDatabase API. The name implies that it adds a database, but it didn't actually create the database. In .NET.NET Aspire 9.2, the AddDatabase API now creates a database for the following hosting integrations:

ホスティング統合 API リファレンス
📦 Aspire.Hosting.SqlServer AddDatabase
📦 Aspire.Hosting.PostgreSql AddDatabase

The Azure SQL and AzurePostgreSQL hosting integrations also expose AddDatabase APIs which work with their respective RunAsContainer methods. For more information, see Understand Azure integration APIs.

By default, .NET.NET Aspire will create an empty database if it doesn't exist. You can also optionally provide a custom script to run during creation for advanced setup or seeding.

Example using Postgres:

var builder = DistributedApplication.CreateBuilder(args);

var postgres = builder.AddPostgres("pg1");

postgres.AddDatabase("todoapp")
    .WithCreationScript($$"""
        CREATE DATABASE {{databaseName}}
            ENCODING = 'UTF8';
        """);

For more information and examples of using the AddDatabase API, see:

The following hosting integrations don't currently support database creation:

☁️ Azure integration updates

In .NET Aspire 9.2, we've made significant updates to Azure integrations, including:

⚙️ Configure Azure Container Apps environments

.NET .NET Aspire 9.2 introduces AddAzureContainerAppEnvironment, allowing you to define an Azure Container App environment directly in your app model. This adds an AzureContainerAppsEnvironmentResource that lets you configure the environment and its supporting infrastructure (like container registries and volume file shares) using C# and the Azure.Provisioning APIs—without relying on azd for infrastructure generation.

重要

This uses a different resource naming scheme than azd. If you're upgrading an existing deployment, this may create duplicate resources. To avoid this, you can opt into azd's naming convention:

var builder = DistributedApplication.CreateBuilder(args);

builder.AddAzureContainerAppEnvironment("my-env")
       .WithAzdResourceNaming();

For more information, see Configure Azure Container Apps environments.

🆕 New Client integrations: AzurePostgreSQL (Npgsql & EF Core)

.NET .NET Aspire 9.2 adds client integrations for working with Azure Database for PostgreSQL, supporting both local development and secure cloud deployment.

These integrations automatically use Managed Identity (Entra ID) in the cloud and during local development by default. They also support username/password, if configured in your AppHost. No application code changes are required to switch between authentication models.

In AppHost:

var postgres = builder.AddAzurePostgresFlexibleServer("pg")
                      .AddDatabase("postgresdb");

builder.AddProject<Projects.MyService>()
       .WithReference(postgres);

In MyService:

builder.AddAzureNpgsqlDbContext<MyDbContext>("postgresdb");

🖇️ Resource Deep Linking for Cosmos DB, Event Hubs, Service Bus, and OpenAI

CosmosDB databases and containers, EventHub hubs, ServiceBus queues/topics, and AzureOpenAI deployments now support resource deep linking. This allows connection information to target specific child resources—like a particular Cosmos DB container, Event Hubs, or OpenAI deployment—rather than just the top-level account or namespace.

Hosting integrations preserve the full resource hierarchy in connection strings, and client integrations can resolve and inject clients scoped to those specific resources.

AppHost:

var builder = DistributedApplication.CreateBuilder(args);

var cosmos = builder.AddAzureCosmosDB("cosmos")
                    .RunAsPreviewEmulator(e => e.WithDataExplorer());

var db = cosmos.AddCosmosDatabase("appdb");
db.AddContainer("todos", partitionKey: "/userId");
db.AddContainer("users", partitionKey: "/id");

builder.AddProject<Projects.TodoApi>("api")
       .WithReference(db);

In the API project:

var builder = WebApplication.CreateBuilder(args);

builder.AddAzureCosmosDatabase("appdb")
       .AddKeyedContainer("todos")
       .AddKeyedContainer("users");

app.MapPost("/todos", async ([FromKeyedServices("todos")] Container container, TodoItem todo) =>
{
    todo.Id = Guid.NewGuid().ToString();
    await container.CreateItemAsync(todo, new PartitionKey(todo.UserId));
    return Results.Created($"/todos/{todo.Id}", todo);
});

This makes it easy and convenient to use the SDKs to interact with specific resources directly—without extra wiring or manual configuration. It's especially useful in apps that deal with multiple containers or Azure services.

🛡️ Improved Managed Identity defaults

Starting in .NET.NET Aspire 9.2, each Azure Container App now gets its own dedicated managed identity by default. This is a significant change from previous versions, where all apps shared a single, highly privileged identity.

This change strengthens Aspire's secure by default posture:

  • Each app only gets access to the Azure resources it needs.
  • It enforces the principle of least privilege.
  • It provides better isolation between apps in multi-service environments.

By assigning identities individually, Aspire can now scope role assignments more precisely—improving security, auditability, and alignment with Azure best practices.

This is a behavioral breaking change and may impact apps using:

  • Azure SQL Server - Azure SQL only supports one Azure AD admin. With multiple identities, only the last deployed app will be granted admin access by default. Other apps will need explicit users and role assignments.

  • Azure PostgreSQL - The app that creates the database becomes the owner. Other apps (like those running migrations or performing data operations) will need explicit GRANT permissions to access the database correctly.

See the breaking changes page for more details.

This new identity model is an important step toward more secure and maintainable applications in Aspire. While it introduces some setup considerations, especially for database integrations, it lays the groundwork for better default security across the board.

🔑 Least-privilege role assignment functionality

.NET .NET Aspire now supports APIs for modeling least-privilege role assignments when deploying to. This enables more secure defaults by allowing you to define exactly which roles each app needs for specific Azure resources.

var builder = DistributedApplication.CreateBuilder(args);

var storage = builder.AddAzureStorage("storage")
                     .RunAsEmulator(c => c.WithLifetime(ContainerLifetime.Persistent));

var blobs = storage.AddBlobs("blobs");

builder.AddProject<Projects.AzureContainerApps_ApiService>("api")
       .WithExternalHttpEndpoints()
       .WithReference(blobs)
       .WithRoleAssignments(storage, StorageBuiltInRole.StorageBlobDataContributor);

In this example, the API project is granted Storage Blob Data Contributor only for the referenced storage account. This avoids over-provisioning permissions and helps enforce the principle of least privilege.

Each container app automatically gets its own managed identity, and Aspire now generates the necessary role assignment infrastructure for both default and per-reference roles. When targeting existing Azure resources, role assignments are scoped correctly using separate Bicep resources.

1️⃣ First-class Azure Key Vault Secret support

Aspire now supports IAzureKeyVaultSecretReference, a new primitive for modeling secrets directly in the app model. This replaces BicepSecretOutputReference and avoids creating a separate Key Vault per resource.

次のことができるようになりました。

  • Add a shared Key Vault in C#
  • Configure services that support keys (e.g., Redis, Cosmos DB) to store their secrets there
  • Reference those secrets in your app as environment variables or via the Key Vault config provider

Use KeyVault directly in your api:

var builder = DistributedApplication.CreateBuilder(args);

var vault = builder.AddAzureKeyVault("kv");

var redis = builder.AddAzureRedis("redis")
                   .WithAccessKeyAuthentication(vault);

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

Let the compute environment handle the secret management for you:

var redis = builder.AddAzureRedis("redis")
                   .WithAccessKeyAuthentication();

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

Previous behavior:

azd created and managed secrets using a key vault per resource, with no visibility in the app model. Secrets were handled implicitly and couldn't be customized in C#.

New behavior in 9.2:

Calling WithKeyAccessAuthentication or WithPasswordAuthentication now creates an actual AzureKeyVaultResource (or accepts a reference to one), and stores connection strings there. Secret names follow the pattern connectionstrings--{resourcename} to prevent naming conflicts with other vault entries.

🔒 Improved default permissions for Azure Key Vault references

When referencing a Key Vault, Aspire previously granted the broad Key Vault Administrator role by default. In 9.2, this has been changed to Key Vault Secrets User, which provides read-only access to secrets—suitable for most application scenarios.

This update continues the security-focused improvements in this release.

🚀 Deployment improvements

We're excited to announce several new deployment features in .NET.NET Aspire 9.2, including:

📦 Publishers (Preview)

Publishers are a new extensibility point in .NET.NET Aspire that allow you to define how your distributed application gets transformed into deployable assets. Rather than relying on an intermediate manifest format, publishers can now plug directly into the application model to generate Docker Compose files, Kubernetes manifests, Azure resources, or whatever else your environment needs.

When .NET.NET Aspire launched, it introduced a deployment manifest format—a serialized snapshot of the application model. While useful it burdened deployment tools with interpreting the manifest and resource authors with ensuring accurate serialization. This approach also complicated schema evolution and target-specific behaviors.

Publishers simplify this process by working directly with the full application model in-process, enabling richer, more flexible, and maintainable publishing experiences.

The following NuGet packages expose preview publishers:

重要

The Docker and Kubernetes publishers were contributed by community contributor, Dave Sekula—a great example of the community stepping up to extend the model. 💜 Thank you, Dave!

To use a publisher, add the corresponding NuGet package to your app host project file and then call the Add[Name]Publisher() method in your app host builder.

builder.AddDockerComposePublisher();

ヒント

Publisher registration methods follow the Add[Name]Publisher() convention.

You can also build your own publisher by implementing the publishing APIs and calling your custom registration method. Some publishers are still in preview, and the APIs are subject to change. The goal is to provide a more flexible and extensible way to publish distributed applications, making it easier to adapt to different deployment environments and scenarios.

🆕 Aspire CLI (Preview)

.NET .NET Aspire 9.2 introduces the new aspire CLI, an experimental tool for creating, running, and publishing Aspire applications from the command line. It provides a rich, interactive experience tailored for Aspire users.

The CLI is available as a .NET tool and can be installed with:

dotnet tool install --global aspire.cli --prerelease

使用例:

aspire new
aspire run
aspire add redis
aspire publish --publisher docker-compose

Available commands:

  • new <template> – Create a new Aspire sample project
  • run – Run an Aspire app host in development mode
  • add <integration> – Add an integration to your project
  • publish – Generate deployment artifacts from your app host

🧪 The CLI is experimental and in preview. We're exploring how to make it a first-class experience for .NET.NET Aspire users—your feedback is welcome!

🧪 Testing template updates

The xUnit testing project template now supports a version selector, allowing the user to select either:

  • v2: The previous xUnit testing experience.
  • v3: The new xUnit testing experience and template.
  • v3 with Microsoft Test Platform: The next xUnit testing experience, template and uses the Microsoft Testing Platform.

By default, to the v3 experience. 詳細については、以下を参照してください。

Both v3 versions are only supported with .NET.NET Aspire 9.2 or later.

💔 Breaking changes

With every release, we strive to make .NET.NET Aspire better. However, some changes may break existing functionality. The following breaking changes are introduced in .NET.NET Aspire 9.2: