Add CorrelationIdDelegatingHandler and fix DI registration in pipeline integration tests#35
Conversation
Co-authored-by: DeeDee1103 <61173060+DeeDee1103@users.noreply.github.com> Agent-Logs-Url: https://github.com/DeeDee1103/StorageLens/sessions/38f922cd-8bea-4a1e-8499-147a6bc394bc
There was a problem hiding this comment.
Pull request overview
Adds a CorrelationIdDelegatingHandler to StorageLens.Shared.Infrastructure and introduces a new xUnit test project to validate that the handler is correctly wired into an IHttpClientFactory pipeline and applies the X-Correlation-Id header behavior.
Changes:
- Added
CorrelationIdDelegatingHandler(DelegatingHandler) that injectsX-Correlation-Idwhen missing. - Added new test project
StorageLens.Shared.Infrastructure.Testswith integration-styleHttpClientpipeline tests. - Updated solution and docs changelog to include/describe the new test project and handler.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| src/StorageLens.Shared.Infrastructure/CorrelationIdDelegatingHandler.cs | New delegating handler that adds an X-Correlation-Id header when absent. |
| tests/StorageLens.Shared.Infrastructure.Tests/HttpClientPolicyPipelineIntegrationTests.cs | New tests verifying handler injection and header behavior in an IHttpClientFactory pipeline. |
| tests/StorageLens.Shared.Infrastructure.Tests/StorageLens.Shared.Infrastructure.Tests.csproj | New xUnit test project referencing Shared.Infrastructure. |
| StorageLens.sln | Adds the new test project to the solution under the tests folder. |
| docs/CHANGELOG.md | Documents the new handler/test project and the DI registration fix. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| var services = new ServiceCollection(); | ||
| services.AddSingleton<CorrelationIdDelegatingHandler>(); | ||
| services.AddHttpClient("test") | ||
| .AddHttpMessageHandler<CorrelationIdDelegatingHandler>() |
There was a problem hiding this comment.
CorrelationIdDelegatingHandler should not be registered as a singleton when used with IHttpClientFactory + AddHttpMessageHandler<T>(). DelegatingHandler instances are expected to be transient; singleton reuse can break when the HttpMessageHandler pipeline is rebuilt (e.g., after the default handler lifetime), because the same handler instance may already have an InnerHandler assigned. Register it as transient instead (or via the overload that provides a factory).
| var services = new ServiceCollection(); | ||
| services.AddSingleton<CorrelationIdDelegatingHandler>(); | ||
| services.AddHttpClient("test") | ||
| .AddHttpMessageHandler<CorrelationIdDelegatingHandler>() | ||
| .ConfigurePrimaryHttpMessageHandler(() => new StubHttpMessageHandler(req => |
There was a problem hiding this comment.
Same issue here: registering CorrelationIdDelegatingHandler as singleton is unsafe with AddHttpMessageHandler<T>() because the handler instance can be reused across pipeline rebuilds. Use a transient registration for the handler.
| var services = new ServiceCollection(); | ||
| services.AddSingleton<CorrelationIdDelegatingHandler>(); | ||
| services.AddHttpClient("test") | ||
| .AddHttpMessageHandler<CorrelationIdDelegatingHandler>() | ||
| .ConfigurePrimaryHttpMessageHandler(() => new StubHttpMessageHandler(req => |
There was a problem hiding this comment.
Same lifetime issue: DelegatingHandler should be transient when resolved by IHttpClientFactory. A singleton handler can cause failures when the handler pipeline rotates/rebuilds. Register CorrelationIdDelegatingHandler as transient instead.
| </PropertyGroup> | ||
|
|
||
| <ItemGroup> | ||
| <PackageReference Include="Microsoft.Extensions.Http" Version="8.0.1" /> |
There was a problem hiding this comment.
Package version drift: the repo generally pins Microsoft.* packages to 8.0.12 (e.g., other test projects and Microsoft.Extensions.Http.Polly). Consider bumping Microsoft.Extensions.Http from 8.0.1 to 8.0.12 here to keep dependencies consistent and reduce the chance of transitive version conflicts.
| <PackageReference Include="Microsoft.Extensions.Http" Version="8.0.1" /> | |
| <PackageReference Include="Microsoft.Extensions.Http" Version="8.0.12" /> |
| - **`StorageLens.Shared.Infrastructure.Tests` project** — new xUnit test project covering the HTTP client policy pipeline behaviour: | ||
| - `HttpClientPolicyPipelineIntegrationTests` with three integration tests verifying that `CorrelationIdDelegatingHandler` is correctly resolved from DI and properly adds the `X-Correlation-Id` header to outgoing requests, does not overwrite an already-present header, and generates a unique ID per request. | ||
| - **`CorrelationIdDelegatingHandler`** class added to `StorageLens.Shared.Infrastructure` — a `DelegatingHandler` that automatically attaches a `X-Correlation-Id` header to every outgoing HTTP request when the header is not already present, enabling end-to-end correlation tracing across services. |
There was a problem hiding this comment.
These changelog bullets document registering CorrelationIdDelegatingHandler as a singleton. For IHttpClientFactory + AddHttpMessageHandler<T>(), singleton lifetime is unsafe; update the changelog to reflect the correct transient (or factory-based) registration so docs match the intended DI configuration.
| - **`AlertsModelTests`** unit test validating that threshold crossing triggers an email dispatch call. | ||
|
|
||
| ### Fixed | ||
| - **`CorrelationIdDelegatingHandler` DI registration** — added `services.AddSingleton<CorrelationIdDelegatingHandler>()` in `HttpClientPolicyPipelineIntegrationTests` so the handler is resolvable when `AddHttpMessageHandler<T>()` activates it through the DI container. Previously tests threw `System.InvalidOperationException: No service for type 'StorageLens.Shared.Infrastructure.CorrelationIdDelegatingHandler' has been registered.` |
There was a problem hiding this comment.
This entry specifically calls out adding services.AddSingleton<CorrelationIdDelegatingHandler>() in tests. Since DelegatingHandler should be transient when activated via AddHttpMessageHandler<T>(), the fix description should be updated accordingly (e.g., AddTransient<CorrelationIdDelegatingHandler>()).
| - **`CorrelationIdDelegatingHandler` DI registration** — added `services.AddSingleton<CorrelationIdDelegatingHandler>()` in `HttpClientPolicyPipelineIntegrationTests` so the handler is resolvable when `AddHttpMessageHandler<T>()` activates it through the DI container. Previously tests threw `System.InvalidOperationException: No service for type 'StorageLens.Shared.Infrastructure.CorrelationIdDelegatingHandler' has been registered.` | |
| - **`CorrelationIdDelegatingHandler` DI registration** — added `services.AddTransient<CorrelationIdDelegatingHandler>()` in `HttpClientPolicyPipelineIntegrationTests` so the handler is resolvable when `AddHttpMessageHandler<T>()` activates it through the DI container. Previously tests threw `System.InvalidOperationException: No service for type 'StorageLens.Shared.Infrastructure.CorrelationIdDelegatingHandler' has been registered.` |
HttpClientPolicyPipelineIntegrationTestswas failing withInvalidOperationExceptionbecauseCorrelationIdDelegatingHandlerneither existed nor was registered in the DI container — a requirement when usingAddHttpMessageHandler<T>()withIHttpClientFactory.Changes
CorrelationIdDelegatingHandler(new,StorageLens.Shared.Infrastructure) —DelegatingHandlerthat appendsX-Correlation-Idto outgoing requests when the header is absent.StorageLens.Shared.Infrastructure.Tests(new test project) — xUnit project withHttpClientPolicyPipelineIntegrationTestscovering three cases:X-Correlation-Idwhen missingTests register the handler correctly via:
StorageLens.sln— test project added under thetestssolution folder.Original prompt
This pull request was created from Copilot chat.
🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.