Skip to content

feat: add Azure Functions middleware for HTTP correlation ID management#562

Merged
samtrion merged 2 commits intomainfrom
feature/azure-functions
Mar 23, 2026
Merged

feat: add Azure Functions middleware for HTTP correlation ID management#562
samtrion merged 2 commits intomainfrom
feature/azure-functions

Conversation

@samtrion
Copy link
Contributor

@samtrion samtrion commented Mar 23, 2026

Summary by CodeRabbit

  • New Features

    • Azure Functions isolated worker middleware and DI extensions for HTTP correlation ID propagation and generation
  • Documentation

    • Added comprehensive README for the Azure Functions package (usage, configuration, examples)
  • Refactor

    • Reorganized component namespaces (AspNetCore, HttpClient, Ulid, TestGenerator)
    • Correlation accessor updated to allow internal assignment
  • Chores

    • Editor/build configuration updates and central package version pinning
  • Tests

    • Added unit and integration tests for Azure Functions middleware and builder extensions

@samtrion samtrion self-assigned this Mar 23, 2026
@samtrion samtrion requested a review from a team as a code owner March 23, 2026 22:05
@samtrion samtrion added the state:ready for merge Indicates that a pull request has been reviewed and approved, and is ready to be merged into the mai label Mar 23, 2026
@samtrion samtrion requested review from benwirren and removed request for a team March 23, 2026 22:05
@samtrion samtrion added the type:feature Indicates a new feature or enhancement to be added. label Mar 23, 2026
@coderabbitai
Copy link

coderabbitai bot commented Mar 23, 2026

Warning

Rate limit exceeded

@samtrion has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 9 minutes and 17 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9c816a78-6492-4b83-8aaf-808c27918fb5

📥 Commits

Reviewing files that changed from the base of the PR and between 9f4f906 and a96edd2.

📒 Files selected for processing (41)
  • .csharpierignore
  • .editorconfig
  • Directory.Build.props
  • Directory.Packages.props
  • Http.Correlation.slnx
  • src/NetEvolve.Http.Correlation.Abstractions/Abstractions/IHttpCorrelationAccessor.cs
  • src/NetEvolve.Http.Correlation.Abstractions/HttpCorrelationBuilder.cs
  • src/NetEvolve.Http.Correlation.Abstractions/HttpCorrelationBuilderExtensions.cs
  • src/NetEvolve.Http.Correlation.Abstractions/NetEvolve.Http.Correlation.Abstractions.csproj
  • src/NetEvolve.Http.Correlation.AspNetCore/ApplicationBuilderExtensions.cs
  • src/NetEvolve.Http.Correlation.AspNetCore/HttpCorrelationAccessor.cs
  • src/NetEvolve.Http.Correlation.AspNetCore/HttpCorrelationMiddleware.cs
  • src/NetEvolve.Http.Correlation.AspNetCore/NetEvolve.Http.Correlation.AspNetCore.csproj
  • src/NetEvolve.Http.Correlation.AspNetCore/ServiceCollectionExtensions.cs
  • src/NetEvolve.Http.Correlation.Azure.Functions/FunctionsCorrelationAccessor.cs
  • src/NetEvolve.Http.Correlation.Azure.Functions/FunctionsCorrelationMiddleware.cs
  • src/NetEvolve.Http.Correlation.Azure.Functions/FunctionsWorkerApplicationBuilderExtensions.cs
  • src/NetEvolve.Http.Correlation.Azure.Functions/NetEvolve.Http.Correlation.Azure.Functions.csproj
  • src/NetEvolve.Http.Correlation.Azure.Functions/README.md
  • src/NetEvolve.Http.Correlation.Azure.Functions/ServiceCollectionExtensions.cs
  • src/NetEvolve.Http.Correlation.HttpClient/HttpClientBuilderExtensions.cs
  • src/NetEvolve.Http.Correlation.HttpClient/HttpCorrelationIdHandler.cs
  • src/NetEvolve.Http.Correlation.TestGenerator/HttpCorrelationBuilderExtensions.cs
  • src/NetEvolve.Http.Correlation.TestGenerator/TestGeneratorCorrelationIdProvider.cs
  • src/NetEvolve.Http.Correlation.Ulid/HttpCorrelationBuilderExtensions.cs
  • src/NetEvolve.Http.Correlation.Ulid/ULIDCorrelationIdProvider.cs
  • tests/NetEvolve.Http.Correlation.AspNetCore.Tests.Integration/HttpCorrelationMiddlewareTests.cs
  • tests/NetEvolve.Http.Correlation.AspNetCore.Tests.Integration/TestBase.cs
  • tests/NetEvolve.Http.Correlation.AspNetCore.Tests.Unit/ApplicationBuilderExtensionsTests.cs
  • tests/NetEvolve.Http.Correlation.AspNetCore.Tests.Unit/HttpCorrelationBuilderExtensionsTests.cs
  • tests/NetEvolve.Http.Correlation.AspNetCore.Tests.Unit/ServiceCollectionExtensionsTests.cs
  • tests/NetEvolve.Http.Correlation.Azure.Functions.Tests.Integration/FunctionsCorrelationMiddlewareTests.cs
  • tests/NetEvolve.Http.Correlation.Azure.Functions.Tests.Integration/NetEvolve.Http.Correlation.Azure.Functions.Tests.Integration.csproj
  • tests/NetEvolve.Http.Correlation.Azure.Functions.Tests.Integration/TestBase.cs
  • tests/NetEvolve.Http.Correlation.Azure.Functions.Tests.Unit/FunctionsWorkerApplicationBuilderExtensionsTests.cs
  • tests/NetEvolve.Http.Correlation.Azure.Functions.Tests.Unit/HttpCorrelationBuilderExtensionsTests.cs
  • tests/NetEvolve.Http.Correlation.Azure.Functions.Tests.Unit/NetEvolve.Http.Correlation.Azure.Functions.Tests.Unit.csproj
  • tests/NetEvolve.Http.Correlation.Azure.Functions.Tests.Unit/ServiceCollectionExtensionsTests.cs
  • tests/NetEvolve.Http.Correlation.HttpClient.Tests.Unit/HttpClientBuilderExtensionsTests.cs
  • tests/NetEvolve.Http.Correlation.TestGenerator.Tests.Unit/HttpCorrelationBuilderExtensionsTests.cs
  • tests/NetEvolve.Http.Correlation.Ulid.Tests.Unit/HttpCorrelationBuilderExtensionsTests.cs

Walkthrough

Reorganized namespaces into component-specific modules, added Azure Functions isolated worker middleware and DI integration with tests, adjusted project and solution files (package/version, internals visibility, root namespace), and updated editor/ignore configurations and test imports.

Changes

Cohort / File(s) Summary
Build & Editor Config
\.csharpierignore, \.editorconfig, Directory.Build.props, Directory.Packages.props
Updated ignore patterns (case-insensitive nuget.config, .verified.*/.received.*), increased XML max line length, marked generated files and suppressed diagnostics, removed global RootNamespace for some projects, and added central package version for Microsoft.Azure.Functions.Worker.Core (2.51.0).
Solution
Http.Correlation.slnx
Removed two script solution items and added a new Azure Functions production project plus its unit and integration test projects.
Abstractions
src/NetEvolve.Http.Correlation.Abstractions/Abstractions/IHttpCorrelationAccessor.cs, src/NetEvolve.Http.Correlation.Abstractions/...csproj
Made CorrelationId settable with internal set and added/updated project RootNamespace and extended InternalsVisibleTo entries for additional friend assemblies.
AspNetCore component
src/NetEvolve.Http.Correlation.AspNetCore/...
Moved types to NetEvolve.Http.Correlation.AspNetCore namespace; HttpCorrelationAccessor now caches/lazily initialises correlation ID; updated project tags and test visibility (InternalsVisibleTo).
HttpClient / TestGenerator / Ulid components
src/NetEvolve.Http.Correlation.HttpClient/..., src/NetEvolve.Http.Correlation.TestGenerator/..., src/NetEvolve.Http.Correlation.Ulid/...
Moved several types into component-specific namespaces (HttpClient, TestGenerator, Ulid) without logic changes.
Azure Functions implementation
src/NetEvolve.Http.Correlation.Azure.Functions/*
Added new Azure Functions package: FunctionsCorrelationAccessor, FunctionsCorrelationMiddleware, DI ServiceCollectionExtensions.AddHttpCorrelation(), FunctionsWorkerApplicationBuilderExtensions.UseHttpCorrelation(), project file, and README documenting behavior and configuration.
Azure Functions integration tests & test infra
tests/...Azure.Functions.Tests.Integration/*
Added integration test project, test base harness (TestBase, TestHttpRequestData, TestHttpResponseData), and comprehensive middleware integration tests validating headers, fallbacks, and generator behavior.
Azure Functions unit tests
tests/...Azure.Functions.Tests.Unit/*
Added unit tests for UseHttpCorrelation, builder extension registration, and DI registrations; included test projects with assembly attributes.
Test files - using directives
tests/...AspNetCore..., tests/...HttpClient..., tests/...TestGenerator..., tests/...Ulid...
Added/updated using directives across existing tests to match namespace reorganizations; no test logic changes.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐇 I hopped through namespaces, tidy and spry,
Azure Functions now dance in the sky,
IDs cached, headers passed along,
Middleware hums a steady song,
Tests clap their paws — everything's sync and spry.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 4.76% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main feature added: Azure Functions middleware for HTTP correlation ID management, which is the primary purpose of the PR.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (7)
.editorconfig (1)

277-277: Fix misleading inline comment in snapshot block.

At Line 277, the comment says “migrations” but this section is for *.{received,verified}.* snapshot-like files. Please rename the comment to avoid confusion.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.editorconfig at line 277, Update the misleading inline comment that
currently reads "Disable all style rules for migrations" to accurately describe
the block for snapshot-like files (e.g. use "Disable all style rules for
snapshot files (e.g. *.{received,verified}.*)") so the comment matches the
section handling files matching *.{received,verified}.*; edit the comment in the
.editorconfig snapshot block accordingly.
src/NetEvolve.Http.Correlation.AspNetCore/HttpCorrelationMiddleware.cs (1)

52-53: Consider null-safety improvement for the accessor resolution.

While ApplicationBuilderExtensions.UseHttpCorrelation validates that IHttpCorrelationAccessor is registered at startup, using the null-forgiving operator (!) on GetService is a potential maintenance risk if the validation is ever bypassed.

🛡️ Optional: Use GetRequiredService for explicit intent
-        var accessor = context.RequestServices.GetService<IHttpCorrelationAccessor>()!;
+        var accessor = context.RequestServices.GetRequiredService<IHttpCorrelationAccessor>();
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/NetEvolve.Http.Correlation.AspNetCore/HttpCorrelationMiddleware.cs`
around lines 52 - 53, The current middleware resolves IHttpCorrelationAccessor
with context.RequestServices.GetService<IHttpCorrelationAccessor>()! which uses
the null-forgiving operator and risks NRE if validation is bypassed; change
resolution to use GetRequiredService<IHttpCorrelationAccessor>() from
Microsoft.Extensions.DependencyInjection (or perform an explicit null-check and
throw a clear InvalidOperationException) so HttpCorrelationMiddleware sets
accessor.HeaderName only when a non-null accessor is returned—update the line in
HttpCorrelationMiddleware where accessor is obtained to use GetRequiredService
or add a guard that references IHttpCorrelationAccessor and provides a clear
error message.
src/NetEvolve.Http.Correlation.Abstractions/Abstractions/IHttpCorrelationAccessor.cs (1)

10-13: XML documentation is outdated for the updated interface scope.

The documentation states "Gets the current Correlation Id from the HttpContext", but with this PR the interface is now also implemented by FunctionsCorrelationAccessor which retrieves the correlation ID from FunctionContext.InvocationId, not HttpContext.

Consider updating the documentation to be more generic:

📝 Suggested documentation update
     /// <summary>
-    /// Gets the current Correlation Id from the <see cref="HttpContext"/>.
+    /// Gets or sets the current Correlation Id.
     /// </summary>
     string CorrelationId { get; internal set; }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/NetEvolve.Http.Correlation.Abstractions/Abstractions/IHttpCorrelationAccessor.cs`
around lines 10 - 13, The XML doc for the IHttpCorrelationAccessor.CorrelationId
property is too specific to HttpContext; update the summary to a generic
description since implementations include FunctionsCorrelationAccessor which
uses FunctionContext.InvocationId (not HttpContext). Locate the CorrelationId
property on the IHttpCorrelationAccessor interface and change the XML summary to
something like "Gets or sets the current correlation id for the current
execution context." and ensure it does not reference HttpContext so it applies
to both HTTP and function-based implementations.
src/NetEvolve.Http.Correlation.Azure.Functions/FunctionsCorrelationAccessor.cs (1)

18-18: Inconsistent default value for HeaderName.

HttpCorrelationAccessor initializes HeaderName to CorrelationConstants.HeaderName1, but FunctionsCorrelationAccessor uses string.Empty. This inconsistency could lead to unexpected behavior if HeaderName is accessed before the middleware sets it.

♻️ Suggested fix for consistency
-    public string HeaderName { get; set; } = string.Empty;
+    public string HeaderName { get; set; } = CorrelationConstants.HeaderName1;

This requires adding a using directive:

 using Microsoft.Azure.Functions.Worker;
 using NetEvolve.Http.Correlation.Abstractions;
+using static NetEvolve.Http.Correlation.Abstractions.CorrelationConstants;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/NetEvolve.Http.Correlation.Azure.Functions/FunctionsCorrelationAccessor.cs`
at line 18, FunctionsCorrelationAccessor currently defaults the HeaderName
property to string.Empty which is inconsistent with HttpCorrelationAccessor;
change the default to CorrelationConstants.HeaderName1 on the HeaderName
auto-property in FunctionsCorrelationAccessor and add the appropriate using for
the namespace that defines CorrelationConstants so the symbol resolves (ensure
no other code relies on the empty-string sentinel).
src/NetEvolve.Http.Correlation.Azure.Functions/FunctionsWorkerApplicationBuilderExtensions.cs (1)

23-31: Consider documenting the BuildServiceProvider trade-off.

Calling BuildServiceProvider() during configuration is generally discouraged as it creates an intermediate container. However, this pattern is acceptable here for fail-fast validation since the scope is immediately disposed and no singleton state is shared with the runtime container.

If this triggers analyzer warnings (e.g., ASP0000), consider suppressing with a comment explaining the validation intent.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/NetEvolve.Http.Correlation.Azure.Functions/FunctionsWorkerApplicationBuilderExtensions.cs`
around lines 23 - 31, Add an explanatory comment around the temporary
BuildServiceProvider()/CreateScope() usage in
FunctionsWorkerApplicationBuilderExtensions to document the trade-off: this
intermediate container is intentionally created only for fail-fast validation of
IHttpCorrelationAccessor and is immediately disposed so it won’t share singleton
state with the runtime container; if your analyzer emits warnings (e.g.,
ASP0000) add a suppression comment referencing the validation intent and point
to ServiceCollectionExtensions.AddHttpCorrelation as the expected registration
path.
tests/NetEvolve.Http.Correlation.Azure.Functions.Tests.Integration/TestBase.cs (1)

74-79: Expose response metadata from the test harness to cover header propagation.

At Line 74 and Line 78, RunAsync(...)/TestRunResult only return accessor state. That prevents direct integration assertions for the middleware’s response-header write behavior after next. Consider returning response headers (or response object) in TestRunResult so tests can validate end-to-end correlation header propagation.

Also applies to: 127-127

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@tests/NetEvolve.Http.Correlation.Azure.Functions.Tests.Integration/TestBase.cs`
around lines 74 - 79, Return response metadata from RunAsync so tests can assert
header propagation: after calling middleware.Invoke(context, next) capture the
response headers (or the Response object) from context.Response and include them
in the TestRunResult; update the TestRunResult type (and its
constructor/consumers) to carry the response headers (e.g., a HeaderDictionary
or response object) in addition to nextCalled and FunctionsCorrelationAccessor
values, and adjust callers to use the new property for end-to-end header
assertions involving FunctionsCorrelationAccessor, RunAsync and
middleware.Invoke.
tests/NetEvolve.Http.Correlation.Azure.Functions.Tests.Unit/HttpCorrelationBuilderExtensionsTests.cs (1)

40-51: Consider extracting the repeated DI registration assertion into a helper.

The predicate/assertion block at Line 40–51 and Line 83–94 is duplicated. A small helper (e.g., AssertProviderRegistration(...)) would make future generator additions cheaper to maintain.

Refactor sketch
+    private static Task AssertProviderRegistration(IServiceCollection services, string expectedFullName) =>
+        Assert.That(services).Contains(s =>
+            s.ServiceType == typeof(IHttpCorrelationIdProvider)
+            && s.Lifetime == ServiceLifetime.Singleton
+            && !string.IsNullOrEmpty(s.ImplementationType!.FullName)
+            && s.ImplementationType.FullName.Equals(expectedFullName, StringComparison.Ordinal)
+        );
...
-            _ = await Assert
-                .That(services)
-                .Contains(s =>
-                    s.ServiceType == typeof(IHttpCorrelationIdProvider)
-                    && s.Lifetime == ServiceLifetime.Singleton
-                    && !string.IsNullOrEmpty(s.ImplementationType!.FullName)
-                    && s.ImplementationType.FullName.Equals(
-                        "NetEvolve.Http.Correlation.Generators.GuidCorrelationIdProvider",
-                        StringComparison.Ordinal
-                    )
-                );
+            await AssertProviderRegistration(
+                services,
+                "NetEvolve.Http.Correlation.Generators.GuidCorrelationIdProvider"
+            );
...
-            _ = await Assert
-                .That(services)
-                .Contains(s =>
-                    s.ServiceType == typeof(IHttpCorrelationIdProvider)
-                    && s.Lifetime == ServiceLifetime.Singleton
-                    && !string.IsNullOrEmpty(s.ImplementationType!.FullName)
-                    && s.ImplementationType.FullName.Equals(
-                        "NetEvolve.Http.Correlation.Generators.GuidV7CorrelationIdProvider",
-                        StringComparison.Ordinal
-                    )
-                );
+            await AssertProviderRegistration(
+                services,
+                "NetEvolve.Http.Correlation.Generators.GuidV7CorrelationIdProvider"
+            );

Also applies to: 83-94

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@tests/NetEvolve.Http.Correlation.Azure.Functions.Tests.Unit/HttpCorrelationBuilderExtensionsTests.cs`
around lines 40 - 51, Extract the duplicated DI registration assertion into a
small helper to avoid repetition: create a method like
AssertProviderRegistration(IServiceCollection services, Type serviceType, string
expectedImplementationFullName) (or a specialized
AssertProviderRegistrationForCorrelation(IServiceCollection services, string
expectedImplementationFullName)) that encapsulates the predicate currently
passed to Assert.That(...).Contains(...) and the subsequent
Assert.That(services.Count).IsEqualTo(1); then replace both duplicated blocks in
HttpCorrelationBuilderExtensionsTests.cs with calls to this helper using
serviceType = typeof(IHttpCorrelationIdProvider) and the implementation full
name "NetEvolve.Http.Correlation.Generators.GuidCorrelationIdProvider".
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@src/NetEvolve.Http.Correlation.Azure.Functions/FunctionsCorrelationAccessor.cs`:
- Line 10: The CorrelationId getter currently dereferences the FunctionContext
property (Context) which is initialized to default! and can be null; update the
FunctionsCorrelationAccessor to defensively check Context before accessing
Context.InvocationId and throw a clear InvalidOperationException (or
ArgumentNullException) with an explanatory message if Context is not set, or
alternatively make Context nullable (FunctionContext?) and document the
initialization requirement—locate the Context property and the CorrelationId
getter to implement the null check and ensure callers get a meaningful exception
instead of a NullReferenceException.

In `@src/NetEvolve.Http.Correlation.Ulid/HttpCorrelationBuilderExtensions.cs`:
- Line 1: Public extension type HttpCorrelationBuilderExtensions was moved to a
new namespace which breaks binary/compiled consumers; restore compatibility by
adding a compatibility shim in the original namespace that forwards to the new
implementation (either re-declare an extension class/methods in the old
namespace that call the methods on the new
NetEvolve.Http.Correlation.Ulid.HttpCorrelationBuilderExtensions, or add proper
TypeForwardedTo attributes if using assembly-level type forwarding). Ensure the
shim exposes the identical public signatures (same extension method names and
parameter types) so existing compiled callers continue to resolve to
HttpCorrelationBuilderExtensions.

---

Nitpick comments:
In @.editorconfig:
- Line 277: Update the misleading inline comment that currently reads "Disable
all style rules for migrations" to accurately describe the block for
snapshot-like files (e.g. use "Disable all style rules for snapshot files (e.g.
*.{received,verified}.*)") so the comment matches the section handling files
matching *.{received,verified}.*; edit the comment in the .editorconfig snapshot
block accordingly.

In
`@src/NetEvolve.Http.Correlation.Abstractions/Abstractions/IHttpCorrelationAccessor.cs`:
- Around line 10-13: The XML doc for the IHttpCorrelationAccessor.CorrelationId
property is too specific to HttpContext; update the summary to a generic
description since implementations include FunctionsCorrelationAccessor which
uses FunctionContext.InvocationId (not HttpContext). Locate the CorrelationId
property on the IHttpCorrelationAccessor interface and change the XML summary to
something like "Gets or sets the current correlation id for the current
execution context." and ensure it does not reference HttpContext so it applies
to both HTTP and function-based implementations.

In `@src/NetEvolve.Http.Correlation.AspNetCore/HttpCorrelationMiddleware.cs`:
- Around line 52-53: The current middleware resolves IHttpCorrelationAccessor
with context.RequestServices.GetService<IHttpCorrelationAccessor>()! which uses
the null-forgiving operator and risks NRE if validation is bypassed; change
resolution to use GetRequiredService<IHttpCorrelationAccessor>() from
Microsoft.Extensions.DependencyInjection (or perform an explicit null-check and
throw a clear InvalidOperationException) so HttpCorrelationMiddleware sets
accessor.HeaderName only when a non-null accessor is returned—update the line in
HttpCorrelationMiddleware where accessor is obtained to use GetRequiredService
or add a guard that references IHttpCorrelationAccessor and provides a clear
error message.

In
`@src/NetEvolve.Http.Correlation.Azure.Functions/FunctionsCorrelationAccessor.cs`:
- Line 18: FunctionsCorrelationAccessor currently defaults the HeaderName
property to string.Empty which is inconsistent with HttpCorrelationAccessor;
change the default to CorrelationConstants.HeaderName1 on the HeaderName
auto-property in FunctionsCorrelationAccessor and add the appropriate using for
the namespace that defines CorrelationConstants so the symbol resolves (ensure
no other code relies on the empty-string sentinel).

In
`@src/NetEvolve.Http.Correlation.Azure.Functions/FunctionsWorkerApplicationBuilderExtensions.cs`:
- Around line 23-31: Add an explanatory comment around the temporary
BuildServiceProvider()/CreateScope() usage in
FunctionsWorkerApplicationBuilderExtensions to document the trade-off: this
intermediate container is intentionally created only for fail-fast validation of
IHttpCorrelationAccessor and is immediately disposed so it won’t share singleton
state with the runtime container; if your analyzer emits warnings (e.g.,
ASP0000) add a suppression comment referencing the validation intent and point
to ServiceCollectionExtensions.AddHttpCorrelation as the expected registration
path.

In
`@tests/NetEvolve.Http.Correlation.Azure.Functions.Tests.Integration/TestBase.cs`:
- Around line 74-79: Return response metadata from RunAsync so tests can assert
header propagation: after calling middleware.Invoke(context, next) capture the
response headers (or the Response object) from context.Response and include them
in the TestRunResult; update the TestRunResult type (and its
constructor/consumers) to carry the response headers (e.g., a HeaderDictionary
or response object) in addition to nextCalled and FunctionsCorrelationAccessor
values, and adjust callers to use the new property for end-to-end header
assertions involving FunctionsCorrelationAccessor, RunAsync and
middleware.Invoke.

In
`@tests/NetEvolve.Http.Correlation.Azure.Functions.Tests.Unit/HttpCorrelationBuilderExtensionsTests.cs`:
- Around line 40-51: Extract the duplicated DI registration assertion into a
small helper to avoid repetition: create a method like
AssertProviderRegistration(IServiceCollection services, Type serviceType, string
expectedImplementationFullName) (or a specialized
AssertProviderRegistrationForCorrelation(IServiceCollection services, string
expectedImplementationFullName)) that encapsulates the predicate currently
passed to Assert.That(...).Contains(...) and the subsequent
Assert.That(services.Count).IsEqualTo(1); then replace both duplicated blocks in
HttpCorrelationBuilderExtensionsTests.cs with calls to this helper using
serviceType = typeof(IHttpCorrelationIdProvider) and the implementation full
name "NetEvolve.Http.Correlation.Generators.GuidCorrelationIdProvider".
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8d0e0098-9fd8-407b-b49c-b19d92e946d5

📥 Commits

Reviewing files that changed from the base of the PR and between 0a496d0 and 2f9ee0c.

📒 Files selected for processing (41)
  • .csharpierignore
  • .editorconfig
  • Directory.Build.props
  • Directory.Packages.props
  • Http.Correlation.slnx
  • src/NetEvolve.Http.Correlation.Abstractions/Abstractions/IHttpCorrelationAccessor.cs
  • src/NetEvolve.Http.Correlation.Abstractions/HttpCorrelationBuilder.cs
  • src/NetEvolve.Http.Correlation.Abstractions/HttpCorrelationBuilderExtensions.cs
  • src/NetEvolve.Http.Correlation.Abstractions/NetEvolve.Http.Correlation.Abstractions.csproj
  • src/NetEvolve.Http.Correlation.AspNetCore/ApplicationBuilderExtensions.cs
  • src/NetEvolve.Http.Correlation.AspNetCore/HttpCorrelationAccessor.cs
  • src/NetEvolve.Http.Correlation.AspNetCore/HttpCorrelationMiddleware.cs
  • src/NetEvolve.Http.Correlation.AspNetCore/NetEvolve.Http.Correlation.AspNetCore.csproj
  • src/NetEvolve.Http.Correlation.AspNetCore/ServiceCollectionExtensions.cs
  • src/NetEvolve.Http.Correlation.Azure.Functions/FunctionsCorrelationAccessor.cs
  • src/NetEvolve.Http.Correlation.Azure.Functions/FunctionsCorrelationMiddleware.cs
  • src/NetEvolve.Http.Correlation.Azure.Functions/FunctionsWorkerApplicationBuilderExtensions.cs
  • src/NetEvolve.Http.Correlation.Azure.Functions/NetEvolve.Http.Correlation.Azure.Functions.csproj
  • src/NetEvolve.Http.Correlation.Azure.Functions/README.md
  • src/NetEvolve.Http.Correlation.Azure.Functions/ServiceCollectionExtensions.cs
  • src/NetEvolve.Http.Correlation.HttpClient/HttpClientBuilderExtensions.cs
  • src/NetEvolve.Http.Correlation.HttpClient/HttpCorrelationIdHandler.cs
  • src/NetEvolve.Http.Correlation.TestGenerator/HttpCorrelationBuilderExtensions.cs
  • src/NetEvolve.Http.Correlation.TestGenerator/TestGeneratorCorrelationIdProvider.cs
  • src/NetEvolve.Http.Correlation.Ulid/HttpCorrelationBuilderExtensions.cs
  • src/NetEvolve.Http.Correlation.Ulid/ULIDCorrelationIdProvider.cs
  • tests/NetEvolve.Http.Correlation.AspNetCore.Tests.Integration/HttpCorrelationMiddlewareTests.cs
  • tests/NetEvolve.Http.Correlation.AspNetCore.Tests.Integration/TestBase.cs
  • tests/NetEvolve.Http.Correlation.AspNetCore.Tests.Unit/ApplicationBuilderExtensionsTests.cs
  • tests/NetEvolve.Http.Correlation.AspNetCore.Tests.Unit/HttpCorrelationBuilderExtensionsTests.cs
  • tests/NetEvolve.Http.Correlation.AspNetCore.Tests.Unit/ServiceCollectionExtensionsTests.cs
  • tests/NetEvolve.Http.Correlation.Azure.Functions.Tests.Integration/FunctionsCorrelationMiddlewareTests.cs
  • tests/NetEvolve.Http.Correlation.Azure.Functions.Tests.Integration/NetEvolve.Http.Correlation.Azure.Functions.Tests.Integration.csproj
  • tests/NetEvolve.Http.Correlation.Azure.Functions.Tests.Integration/TestBase.cs
  • tests/NetEvolve.Http.Correlation.Azure.Functions.Tests.Unit/FunctionsWorkerApplicationBuilderExtensionsTests.cs
  • tests/NetEvolve.Http.Correlation.Azure.Functions.Tests.Unit/HttpCorrelationBuilderExtensionsTests.cs
  • tests/NetEvolve.Http.Correlation.Azure.Functions.Tests.Unit/NetEvolve.Http.Correlation.Azure.Functions.Tests.Unit.csproj
  • tests/NetEvolve.Http.Correlation.Azure.Functions.Tests.Unit/ServiceCollectionExtensionsTests.cs
  • tests/NetEvolve.Http.Correlation.HttpClient.Tests.Unit/HttpClientBuilderExtensionsTests.cs
  • tests/NetEvolve.Http.Correlation.TestGenerator.Tests.Unit/HttpCorrelationBuilderExtensionsTests.cs
  • tests/NetEvolve.Http.Correlation.Ulid.Tests.Unit/HttpCorrelationBuilderExtensionsTests.cs
💤 Files with no reviewable changes (1)
  • Directory.Build.props

@codecov
Copy link

codecov bot commented Mar 23, 2026

Codecov Report

❌ Patch coverage is 94.64286% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 98.22%. Comparing base (39902d9) to head (a96edd2).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
....Azure.Functions/FunctionsCorrelationMiddleware.cs 94.73% 1 Missing and 1 partial ⚠️
....Correlation.AspNetCore/HttpCorrelationAccessor.cs 50.00% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##              main     #562      +/-   ##
===========================================
- Coverage   100.00%   98.22%   -1.78%     
===========================================
  Files           14       18       +4     
  Lines          114      169      +55     
  Branches        10       22      +12     
===========================================
+ Hits           114      166      +52     
- Misses           0        2       +2     
- Partials         0        1       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@samtrion samtrion force-pushed the feature/azure-functions branch from 9f4f906 to a96edd2 Compare March 23, 2026 23:37
@samtrion samtrion merged commit 4f3ba09 into main Mar 23, 2026
14 checks passed
@samtrion samtrion deleted the feature/azure-functions branch March 23, 2026 23:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

state:ready for merge Indicates that a pull request has been reviewed and approved, and is ready to be merged into the mai type:feature Indicates a new feature or enhancement to be added.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant