Skip to content

.NET Aspire release 9.3 content #3368

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 48 commits into from
May 19, 2025
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
ec61daf
Update existing content to address changes mentioned in #3078.
IEvangelist May 6, 2025
e903c07
Add conditional nuget.config for release branch
IEvangelist May 7, 2025
0c19b2b
Add breaking change to fix #3326
IEvangelist May 7, 2025
f48860a
Added a step to print the trigger context
IEvangelist May 7, 2025
87189af
Fix default expanded state
IEvangelist May 7, 2025
8b32ab4
Remove text
IEvangelist May 7, 2025
37f28a2
Tweak TOC
IEvangelist May 7, 2025
1a18613
Fix MD warings
IEvangelist May 7, 2025
a7ab240
Added SKU changes, fixed #3144
IEvangelist May 7, 2025
b04a24a
Remove workflows and let main handle it
adegeo May 7, 2025
6e2bc1f
Sync with main
IEvangelist May 8, 2025
cfa46b8
Sync with main
IEvangelist May 8, 2025
4fddd68
add doc around dashboard telemetry (#2846)
adamint May 8, 2025
d4c13ec
Clean up (#3378)
IEvangelist May 8, 2025
0c8fe4f
Add content for user-assigned managed ids (#3377)
IEvangelist May 8, 2025
954502b
Correct URL to JSON config schema. (#3381)
IEvangelist May 9, 2025
e36694f
Fix build warnings/errors (#3382)
IEvangelist May 9, 2025
a4f2cfa
Remove publisher APIs (#3389)
IEvangelist May 12, 2025
535bef6
Add ACR hosting integration content. (#3383)
IEvangelist May 12, 2025
66248ac
Fixes #3386, adds breaking changes content for Azure SQL Server admin…
IEvangelist May 12, 2025
56e9b0a
Fixes #3224. Move Dapr to community toolkit (#3393)
IEvangelist May 12, 2025
ec4e705
Adds new eventing APIs. (#3392)
IEvangelist May 13, 2025
0aab7e5
Architecture content (#3156)
IEvangelist May 14, 2025
c6d931d
Initial draft of Azure AI Inference content (#3399)
IEvangelist May 14, 2025
48f9f61
Adds Azure App Configuration integration (#3500)
IEvangelist May 15, 2025
e130c17
Apply suggestions from code review
IEvangelist May 16, 2025
390de8d
Apply suggestions from code review
IEvangelist May 16, 2025
9202a87
Update dotnet-aspire-9.3.md
davidfowl May 16, 2025
1633231
Update dotnet-aspire-9.3.md
davidfowl May 17, 2025
a0b0fb5
Update dotnet-aspire-9.3.md
davidfowl May 17, 2025
09ed788
Update dotnet-aspire-9.3.md
davidfowl May 17, 2025
b5adefa
Update dotnet-aspire-9.3.md
davidfowl May 17, 2025
4c3af54
Update dotnet-aspire-9.3.md
davidfowl May 17, 2025
8df5abb
Update dotnet-aspire-9.3.md
davidfowl May 18, 2025
326a5bf
Update dotnet-aspire-9.3.md
davidfowl May 18, 2025
f0d15d3
Update dotnet-aspire-9.3.md
davidfowl May 18, 2025
5efd7d1
Update dotnet-aspire-9.3.md
davidfowl May 18, 2025
60fa185
Update dotnet-aspire-9.3.md
davidfowl May 18, 2025
8fb6517
Update dotnet-aspire-9.3.md
davidfowl May 18, 2025
a5d74ad
Add dashboard screenshots
JamesNK May 18, 2025
5671f02
Apply suggestions from code review
IEvangelist May 18, 2025
e92da02
A bit of clean up
IEvangelist May 19, 2025
3583a08
Fix more links
IEvangelist May 19, 2025
8091a13
Apply suggestions from code review
davidfowl May 19, 2025
bf3124d
Aspire 9.3 What's New Feedback
eerhardt May 19, 2025
42f0529
Merge pull request #3504 from dotnet/eerhardt/whatsnewfeedback9.3
davidfowl May 19, 2025
b9224a6
Fun times... (#3505)
IEvangelist May 19, 2025
b0f2c79
alerts
IEvangelist May 19, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .openpublishing.redirection.json
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,10 @@
{
"source_path_from_root": "/docs/deployment/azure/local-provisioning.md",
"redirect_url": "/dotnet/aspire/azure/local-provisioning"
},
{
"source_path_from_root": "/docs/frameworks/dapr.md",
"redirect_url": "/dotnet/aspire/azure/dapr"
}
]
}
38 changes: 10 additions & 28 deletions docs/app-host/eventing.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,21 @@ All of the preceding events are analogous to the [app host life cycles](xref:dot

To subscribe to the built-in app host events, use the eventing API. After you have a distributed application builder instance, walk up to the <xref:Aspire.Hosting.IDistributedApplicationBuilder.Eventing?displayProperty=nameWithType> property and call the <xref:Aspire.Hosting.Eventing.IDistributedApplicationEventing.Subscribe``1(System.Func{``0,System.Threading.CancellationToken,System.Threading.Tasks.Task})> API. Consider the following sample app host _Program.cs_ file:

:::code source="snippets/AspireApp/AspireApp.AppHost/Program.cs" highlight="17-25,27-35,37-45":::
:::code source="snippets/AspireApp/AspireApp.AppHost/Program.cs":::

The preceding code is based on the starter template with the addition of the calls to the `Subscribe` API. The `Subscribe<T>` API returns a <xref:Aspire.Hosting.Eventing.DistributedApplicationEventSubscription> instance that you can use to unsubscribe from the event. It's common to discard the returned subscriptions, as you don't usually need to unsubscribe from events as the entire app is torn down when the app host is shut down.

When the app host is run, by the time the .NET Aspire dashboard is displayed, you should see the following log output in the console:

:::code language="Plaintext" source="snippets/AspireApp/AspireApp.AppHost/Console.txt" highlight="2,10,16":::
:::code language="Plaintext" source="snippets/AspireApp/AspireApp.AppHost/Console.txt" highlight="2,10-14,20":::

The log output confirms that event handlers are executed in the order of the app host life cycle events. The subscription order doesn't affect execution order. The `BeforeStartEvent` is triggered first, followed by `AfterEndpointsAllocatedEvent`, and finally `AfterResourcesCreatedEvent`.
The log output confirms that event handlers are executed in the order of the app host life cycle events. The subscription order doesn't affect execution order. The `BeforeStartEvent` is triggered first, followed by `AfterEndpointsAllocatedEvent`, then each resource has its `ResourceEndpointsAllocatedEvent` event fired, and finally `AfterResourcesCreatedEvent`.

## Resource eventing

In addition to the app host events, you can also subscribe to resource events. Resource events are raised specific to an individual resource. Resource events are defined as implementations of the <xref:Aspire.Hosting.Eventing.IDistributedApplicationResourceEvent> interface. The following resource events are available in the listed order:

1. `InitializeResourceEvent`: Raised by orchestrators to signal to resources that they should initialize themselves.
1. <xref:Aspire.Hosting.ApplicationModel.ConnectionStringAvailableEvent>: Raised when a connection string becomes available for a resource.
1. <xref:Aspire.Hosting.ApplicationModel.BeforeResourceStartedEvent>: Raised before the orchestrator starts a new resource.
1. <xref:Aspire.Hosting.ApplicationModel.ResourceReadyEvent>: Raised when a resource initially transitions to a ready state.
Expand All @@ -48,13 +49,13 @@ In addition to the app host events, you can also subscribe to resource events. R

To subscribe to resource events, use the eventing API. After you have a distributed application builder instance, walk up to the <xref:Aspire.Hosting.IDistributedApplicationBuilder.Eventing?displayProperty=nameWithType> property and call the <xref:Aspire.Hosting.Eventing.IDistributedApplicationEventing.Subscribe``1(Aspire.Hosting.ApplicationModel.IResource,System.Func{``0,System.Threading.CancellationToken,System.Threading.Tasks.Task})> API. Consider the following sample app host _Program.cs_ file:

:::code source="snippets/AspireApp/AspireApp.ResourceAppHost/Program.cs" highlight="8-17,19-28,30-39":::
:::code source="snippets/AspireApp/AspireApp.ResourceAppHost/Program.cs":::

The preceding code subscribes to the `ResourceReadyEvent`, `ConnectionStringAvailableEvent`, and `BeforeResourceStartedEvent` events on the `cache` resource. When <xref:Aspire.Hosting.RedisBuilderExtensions.AddRedis*> is called, it returns an <xref:Aspire.Hosting.ApplicationModel.IResourceBuilder`1> where `T` is a <xref:Aspire.Hosting.ApplicationModel.RedisResource>. The resource builder exposes the resource as the <xref:Aspire.Hosting.ApplicationModel.IResourceBuilder`1.Resource?displayProperty=nameWithType> property. The resource in question is then passed to the `Subscribe` API to subscribe to the events on the resource.
The preceding code subscribes to the `InitializeResourceEvent`, `ResourceReadyEvent`, `ConnectionStringAvailableEvent`, and `BeforeResourceStartedEvent` events on the `cache` resource. When <xref:Aspire.Hosting.RedisBuilderExtensions.AddRedis*> is called, it returns an <xref:Aspire.Hosting.ApplicationModel.IResourceBuilder`1> where `T` is a <xref:Aspire.Hosting.ApplicationModel.RedisResource>. The resource builder exposes the resource as the <xref:Aspire.Hosting.ApplicationModel.IResourceBuilder`1.Resource?displayProperty=nameWithType> property. The resource in question is then passed to the `Subscribe` API to subscribe to the events on the resource.

When the app host is run, by the time the .NET Aspire dashboard is displayed, you should see the following log output in the console:

:::code language="Plaintext" source="snippets/AspireApp/AspireApp.ResourceAppHost/Console.txt" highlight="8,10,12":::
:::code language="Plaintext" source="snippets/AspireApp/AspireApp.ResourceAppHost/Console.txt" highlight="8,10,12,18":::

> [!NOTE]
> Some events are blocking. For example, when the `BeforeResourceStartEvent` is published, the startup of the resource will be blocked until all subscriptions for that event on a given resource have completed executing. Whether an event is blocking or not depends on how it is published (see the following section).
Expand Down Expand Up @@ -105,28 +106,9 @@ The preceding code:

When this app host is run, the life cycle hook is executed for each event. The following output is generated:

```Output
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.
```

The preferred way to hook into the app host life cycle is to use the eventing API. For more information, see [Eventing in .NET Aspire](#eventing-in-net-aspire).
:::code language="Plaintext" source="../fundamentals/snippets/lifecycles/AspireApp/AspireApp.AppHost/Console.txt" highlight="2,10,16":::

The preferred way to hook into the app host life cycle is to use the eventing API. For more information, see [App host eventing](#app-host-eventing).

## See also

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Aspire.Hosting.AppHost" Version="9.2.1" />
<PackageReference Include="Aspire.Hosting.Redis" Version="9.2.1" />
<PackageReference Include="Aspire.Hosting.AppHost" Version="9.3.0-preview.1.25262.2" />
<PackageReference Include="Aspire.Hosting.Redis" Version="9.3.0-preview.1.25262.2" />
</ItemGroup>

</Project>
12 changes: 8 additions & 4 deletions docs/app-host/snippets/AspireApp/AspireApp.AppHost/Console.txt
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
info: Program[0]
1. BeforeStartEvent
info: Aspire.Hosting.DistributedApplication[0]
Aspire version: 9.0.0
Aspire version: 9.3.0-preview.1.25262.2+6d54dc081cd2e7ea435e33f7c0e62ff6946ae66d
info: Aspire.Hosting.DistributedApplication[0]
Distributed application starting.
info: Aspire.Hosting.DistributedApplication[0]
Application host directory is: ..\AspireApp\AspireApp.AppHost
Application host directory is: ../AspireApp/AspireApp.AppHost
info: Program[0]
2. AfterEndpointsAllocatedEvent
3. 'aspire-dashboard' ResourceEndpointsAllocatedEvent
3. 'cache' ResourceEndpointsAllocatedEvent
3. 'apiservice' ResourceEndpointsAllocatedEvent
3. 'webfrontend' ResourceEndpointsAllocatedEvent
info: Aspire.Hosting.DistributedApplication[0]
Now listening on: https://localhost:17178
info: Aspire.Hosting.DistributedApplication[0]
Login to the dashboard at https://localhost:17178/login?t=<YOUR_TOKEN>
info: Program[0]
3. AfterResourcesCreatedEvent
4. AfterResourcesCreatedEvent
info: Aspire.Hosting.DistributedApplication[0]
Distributed application started. Press Ctrl+C to shut down.
Distributed application started. Press Ctrl+C to shut down.
13 changes: 12 additions & 1 deletion docs/app-host/snippets/AspireApp/AspireApp.AppHost/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,17 @@
.WithReference(apiService)
.WaitFor(apiService);

builder.Eventing.Subscribe<ResourceEndpointsAllocatedEvent>(
(@event, cancellationToken) =>
{
// The event doesn't expose an IServiceProvider, just write to the console.
Console.WriteLine($"""
3. '{@event.Resource.Name}' ResourceEndpointsAllocatedEvent
""");

return Task.CompletedTask;
});

builder.Eventing.Subscribe<BeforeStartEvent>(
static (@event, cancellationToken) =>
{
Expand All @@ -39,7 +50,7 @@
{
var logger = @event.Services.GetRequiredService<ILogger<Program>>();

logger.LogInformation("3. AfterResourcesCreatedEvent");
logger.LogInformation("4. AfterResourcesCreatedEvent");

return Task.CompletedTask;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Aspire.Hosting.AppHost" Version="9.2.1" />
<PackageReference Include="Aspire.Hosting.Redis" Version="9.2.1" />
<PackageReference Include="Aspire.Hosting.AppHost" Version="9.3.0-preview.1.25262.2" />
<PackageReference Include="Aspire.Hosting.Redis" Version="9.3.0-preview.1.25262.2" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
info: Aspire.Hosting.DistributedApplication[0]
Aspire version: 9.0.0
Aspire version: 9.3.0
info: Aspire.Hosting.DistributedApplication[0]
Distributed application starting.
info: Aspire.Hosting.DistributedApplication[0]
Application host directory is: ..\AspireApp\AspireApp.AppHost
Application host directory is: ../AspireApp/AspireApp.AppHost
info: Program[0]
1. ConnectionStringAvailableEvent
1. InitializeResourceEvent
info: Program[0]
2. BeforeResourceStartedEvent
2. ConnectionStringAvailableEvent
info: Program[0]
3. ResourceReadyEvent
3. BeforeResourceStartedEvent
info: Aspire.Hosting.DistributedApplication[0]
Now listening on: https://localhost:17222
info: Aspire.Hosting.DistributedApplication[0]
Login to the dashboard at https://localhost:17222/login?t=<YOUR_TOKEN>
info: Program[0]
4. ResourceReadyEvent
info: Aspire.Hosting.DistributedApplication[0]
Distributed application started. Press Ctrl+C to shut down.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,17 @@
{
var logger = @event.Services.GetRequiredService<ILogger<Program>>();

logger.LogInformation("3. ResourceReadyEvent");
logger.LogInformation("4. ResourceReadyEvent");

return Task.CompletedTask;
});

builder.Eventing.Subscribe<InitializeResourceEvent>(cache.Resource,
static (@event, cancellationToken) =>
{
var logger = @event.Services.GetRequiredService<ILogger<Program>>();

logger.LogInformation("1. InitializeResourceEvent");

return Task.CompletedTask;
});
Expand All @@ -22,7 +32,7 @@
{
var logger = @event.Services.GetRequiredService<ILogger<Program>>();

logger.LogInformation("2. BeforeResourceStartedEvent");
logger.LogInformation("3. BeforeResourceStartedEvent");

return Task.CompletedTask;
});
Expand All @@ -33,7 +43,7 @@
{
var logger = @event.Services.GetRequiredService<ILogger<Program>>();

logger.LogInformation("1. ConnectionStringAvailableEvent");
logger.LogInformation("2. ConnectionStringAvailableEvent");

return Task.CompletedTask;
});
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading