Skip to content

[Blazor] WebAssembly service defaults template for Aspire integration #64574

@javiercn

Description

@javiercn

Summary

Create a blazor-wasm-aspire-servicedefaults project template (similar to maui-aspire-servicedefaults) that provides the necessary infrastructure for Blazor WebAssembly applications to integrate with Aspire.

Background

Currently, integrating Blazor WebAssembly with Aspire requires significant manual setup including:

  • Custom JS initializer to fetch configuration and inject environment variables
  • WebAssembly-compatible OTLP exporters (standard exporters use blocking patterns that deadlock in single-threaded WASM)
  • Service discovery and resilience configuration
  • Manual OpenTelemetry provider initialization (due to lack of IHostedService support)

The MAUI team has created maui-aspire-servicedefaults template that provides a similar experience. See: https://learn.microsoft.com/dotnet/maui/data-cloud/aspire-integration

Proposed Solution

Create a template that generates a *.ClientServiceDefaults project containing:

1. JS Initializer (*.lib.module.js)

export async function onRuntimeConfigLoaded(config) {
    const response = await fetch('/_blazor/_configuration');
    if (response.ok) {
        const serverConfig = await response.json();
        const envVars = serverConfig?.webAssembly?.environment;
        if (envVars) {
            config.environmentVariables ??= {};
            for (const [key, value] of Object.entries(envVars)) {
                config.environmentVariables[key.replaceAll(':', '__')] = value;
            }
        }
    }
}

2. ClientServiceDefaults Extensions

public static WebAssemblyHostBuilder AddBlazorClientServiceDefaults(this WebAssemblyHostBuilder builder)
{
    builder.ConfigureBlazorClientOpenTelemetry();
    builder.Services.AddServiceDiscovery();
    builder.Services.ConfigureHttpClientDefaults(http =>
    {
        http.AddStandardResilienceHandler();
        http.AddServiceDiscovery();
    });
    return builder;
}

3. WebAssembly-compatible OTLP Exporters

Custom exporters that use fire-and-forget async HTTP calls instead of blocking patterns:

  • WebAssemblyOtlpTraceExporter
  • WebAssemblyOtlpMetricExporter
  • WebAssemblyOtlpLogExporter
  • TaskBasedBatchExportProcessor<T>

4. Package References

  • Microsoft.Extensions.ServiceDiscovery
  • Microsoft.Extensions.Http.Resilience
  • OpenTelemetry.Extensions.Hosting
  • OpenTelemetry.Instrumentation.Http
  • OpenTelemetry.Instrumentation.Runtime
  • OpenTelemetry.Exporter.OpenTelemetryProtocol

Usage

dotnet new blazor-wasm-aspire-servicedefaults -n MyApp.ClientServiceDefaults
dotnet sln add MyApp.ClientServiceDefaults
dotnet add MyBlazorApp.csproj reference MyApp.ClientServiceDefaults

Then in the Blazor WASM Program.cs:

var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.Configuration.AddEnvironmentVariables(); // Until runtime support is added
builder.AddBlazorClientServiceDefaults();
// ...

Dependencies

This template's complexity can be reduced once the following are addressed:

  • Support hosted services in WebAssemblyHost #63637 - IHostedService support in WebAssembly (removes need for manual provider initialization)
  • Environment variables in IConfiguration by default (removes need for AddEnvironmentVariables())
  • Native WASM-compatible OTLP exporters in OpenTelemetry SDK

Related Issues

Part of .NET 11.0 Blazor + Aspire integration improvements

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-blazorIncludes: Blazor, Razor ComponentsenhancementThis issue represents an ask for new feature or an enhancement to an existing one

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions