-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Support hosted services in WebAssemblyHost #63814
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
Support hosted services in WebAssemblyHost #63814
Conversation
Co-authored-by: javiercn <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR adds hosted service (IHostedService) lifecycle management to WebAssemblyHost, enabling Blazor WebAssembly applications to use background services automatically. This addresses the limitation where services registered with AddHostedService were previously ignored in WebAssembly applications, and was specifically requested to support libraries like OpenTelemetry that rely on hosted services.
Key changes:
- Hosted services are automatically started during
RunAsyncCore()after component state restoration - Hosted services are stopped during
DisposeAsync()with error aggregation and logging - Added dependency on
Microsoft.Extensions.Hosting.Abstractionsto enableIHostedServicesupport
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
src/Components/WebAssembly/WebAssembly/src/Microsoft.AspNetCore.Components.WebAssembly.csproj |
Adds reference to Microsoft.Extensions.Hosting.Abstractions package |
src/Components/WebAssembly/WebAssembly/src/Hosting/WebAssemblyHost.cs |
Implements hosted service lifecycle with start/stop methods and disposal integration |
src/Components/WebAssembly/WebAssembly/test/Microsoft.AspNetCore.Components.WebAssembly.Tests.csproj |
Adds reference to Microsoft.Extensions.Hosting.Abstractions for test project |
src/Components/WebAssembly/WebAssembly/test/Hosting/WebAssemblyHostTest.cs |
Adds comprehensive tests for hosted service startup, shutdown, and error handling scenarios |
You can also share your feedback on Copilot code review for a chance to win a $100 gift card. Take the survey.
| var logger = Services.GetService<ILogger<WebAssemblyHost>>(); | ||
| logger?.LogError(ex, "An error occurred stopping hosted services during disposal."); |
Copilot
AI
Dec 1, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider using the LoggerMessage source generator pattern for structured logging. The codebase convention in WebAssemblyRenderer and WebAssemblyNavigationManager uses partial static Log classes with [LoggerMessage] attributes for better performance and consistency. Add a private static partial class Log with a LoggerMessage method for this error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@copilot do this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated to use LoggerMessage source generator pattern with a private static partial Log class. Changes in commit d8752fb.
| } | ||
|
|
||
| // Throw an aggregate exception if there were any exceptions | ||
| if (exceptions is not null) |
Copilot
AI
Dec 1, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The condition check uses is not null which is correct according to nullable reference type conventions. However, the HostedServiceExecutor in src/Hosting/Hosting/src/Internal/HostedServiceExecutor.cs:43 uses != null for the same pattern. Consider using is not null consistently for better code alignment with C# null pattern matching practices, which this codebase already follows (see line 84, 105).
maraf
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me 👍
Co-authored-by: javiercn <[email protected]>
src/Components/WebAssembly/WebAssembly/src/Hosting/WebAssemblyHost.cs
Outdated
Show resolved
Hide resolved
Co-authored-by: javiercn <[email protected]>
src/Components/WebAssembly/WebAssembly/src/Hosting/WebAssemblyHost.cs
Outdated
Show resolved
Hide resolved
Co-authored-by: javiercn <[email protected]>
This PR adds support for hosted services (
IHostedService) inWebAssemblyHost, enabling automatic startup and shutdown of background services in Blazor WebAssembly applications.Description
Applications using
WebAssemblyHost(e.g. Blazor WebAssembly clients) did not support hosted services out of the box. Services registered withAddHostedServicewere ignored when usingWebAssemblyHostBuilder, unlike in applications built withWebApplicationBuilderorHostApplicationBuilder. This prevented libraries like OpenTelemetry from working properly in Blazor WebAssembly apps, as they rely on hosted services for initialization.The implementation adds hosted service lifecycle management to
WebAssemblyHost:IHostedServiceimplementations from the DI containerRunAsyncCore()after component state restorationDisposeAsync()with proper error handlingWebAssemblyHostsimply resolves the executor from DI and calls it at the appropriate times, maintaining clean separation of concernsUsage
Developers can now register hosted services in Blazor WebAssembly apps:
Implementation Details
Microsoft.Extensions.Hosting.Abstractionsreference to enableIHostedServicesupportHostedServiceExecutorclass in the WebAssembly project to encapsulate hosted service lifecycle managementHostedServiceExecutoras a singleton in DI inWebAssemblyHostBuilder.InitializeDefaultServices()HostedServiceExecutoracceptsILogger<HostedServiceExecutor>and handles all exception aggregation and logging internallyWebAssemblyRendererandWebAssemblyNavigationManagerWebAssemblyHostresolves the executor from DI and coordinates its invocation at the right timesTesting
Added comprehensive test coverage:
All existing WebAssemblyHost functionality remains unchanged and all tests pass.
Original prompt
💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.