microsoft / microsoft/aspire

[Aspire.Hosting.Blazor] Generated Gateway.cs crashes with circular DI dependency (UseOtlpExporter + AddStandardResilienceHandler) on .NET 11 preview

Open
#18,272 4 comments 0 reactions 0 assignees View on GitHub
area-integrations blazor-wasm triage:bot-seen
Dominant language
C#
Stars
6.3k
Forks
991
Avg merge
2d 15h
Merged PRs (30d)
196

Description

## Description

The auto-generated `Gateway.cs` script (emitted by `Aspire.Hosting.Blazor`) crashes on startup with an unhandled `System.InvalidOperationException: A circular dependency was detected for the service of type 'Microsoft.Extensions.Logging.ILoggerFactory'` when running on .NET 11 preview 6 nightly (11.0.100-preview.6.26316.109).

## Root Cause

`Gateway.cs` registers both:
1. `ConfigureHttpClientDefaults(http => http.AddStandardResilienceHandler())` (line ~119)
2. `builder.Services.AddOpenTelemetry().UseOtlpExporter()` (line ~172)

`UseOtlpExporter()` enables `IHttpClientFactory` integration internally (`TryEnableIHttpClientFactoryIntegration`). When the factory creates the exporter's HttpClient, it applies the default resilience handler. The resilience handler's `TelemetryOptions` needs `ILoggerFactory`. But `ILoggerFactory` depends on the OTel `LoggerProviderSdk` which depends on the `OtlpLogExporter` which needs `IHttpClientFactory` → **circular**.

### Full circular chain:
```
ILoggerFactory
→ LoggerProviderSdk (OTel)
→ OtlpLogExporter
→ IHttpClientFactory
→ AddStandardResilienceHandler
→ TelemetryOptions (Polly)
→ ILoggerFactory ← CIRCLE
```

## Reproduction

1. Create a Blazor Standalone project with Aspire hosting (`AddBlazorWasmProject` + `AddBlazorGateway` + `WithOtlpExporter`)
2. Use .NET 11 preview 6 SDK (11.0.100-preview.6.26316.109)
3. Use `Aspire.Hosting.Blazor 13.4.5-preview.1.26316.12`
4. Run the AppHost
5. Gateway resource exits with code -532462766 (0xE0434352 = unhandled CLR exception)

## Environment

- .NET SDK: 11.0.100-preview.6.26316.109
- Aspire SDK: 13.4.5
- Aspire.Hosting.Blazor: 13.4.5-preview.1.26316.12
- OS: Windows 11
- Packages in generated Gateway.cs:
- Microsoft.Extensions.Http.Resilience@10.6.0
- OpenTelemetry.Exporter.OpenTelemetryProtocol@1.15.3

## Workaround

Replace `UseOtlpExporter()` with per-signal OTLP export in the generated `Gateway.cs`:

```csharp
// Instead of:
// builder.Services.AddOpenTelemetry().UseOtlpExporter();

// Use per-signal export (doesn't use IHttpClientFactory):
builder.Services.AddOpenTelemetry()
.WithMetrics(m => m.AddOtlpExporter())
.WithTracing(t => t.AddOtlpExporter());
```

Per-signal `AddOtlpExporter()` (on `MeterProviderBuilder`/`TracerProviderBuilder`) doesn't enable `IHttpClientFactory` integration, avoiding the circular dependency.

## Suggested Fix

In the Gateway.cs template emitted by `Aspire.Hosting.Blazor`, either:
1. Replace `UseOtlpExporter()` with per-signal `AddOtlpExporter()` calls
2. Or exclude the OTLP exporter's named HttpClient from the resilience handler defaults
3. Or register the resilience handler AFTER `UseOtlpExporter()` with appropriate filtering

## Stack Trace (abbreviated)

```
System.InvalidOperationException: A circular dependency was detected for the service of type 'Microsoft.Extensions.Logging.ILoggerFactory'.
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(...)
...
at Polly.PollyServiceCollectionExtensions.<>c.b__7_0(TelemetryOptions options, IServiceProvider serviceProvider)
...
at OpenTelemetry.Exporter.OtlpExporterOptionsExtensions.<>c__DisplayClass9_0.b__0()
...
at OpenTelemetry.Exporter.OtlpLogExporter..ctor(...)
...
at Program.$(String[] args) in Gateway.cs:line 47
```

Contributor guide

Open the contributing guide

Research direction

Locate the Gateway.cs template emitted by Aspire.Hosting.Blazor and reproduce the startup failure with the listed .NET 11 preview and Aspire versions. Inspect the registrations for AddStandardResilienceHandler and UseOtlpExporter, then verify that the generated gateway starts without the circular ILoggerFactory dependency while retaining OTLP export.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
observability
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.