Skip to content

Add Configuration references - #129734

Open
rosebyte wants to merge 11 commits into
dotnet:mainfrom
rosebyte:configuration-references
Open

rosebyte wants to merge 11 commits into
dotnet:mainfrom
rosebyte:configuration-references

Conversation

@rosebyte

@rosebyte rosebyte commented Jun 23, 2026 •

Copy link
Copy Markdown
Member

Fixes #127852

@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @dotnet/area-extensions-configuration
See info in area-owners.md if you want to be subscribed.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 introduces a new “configuration references” feature for Microsoft.Extensions.Configuration, enabling configuration values to be expanded via reference syntax (e.g., ref(Target:Key)) and composed values (e.g., format(template, key1, key2, ...)). It does so by adding a contextual configuration source/provider that materializes expanded values on top of upstream providers, plus a fairly comprehensive new test suite.

Changes:

  • Adds a new reference rule model + pattern matcher (ReferenceRule, KeyPattern) and a contextual configuration provider (ReferenceConfigurationProvider) to materialize expanded values and mirror subtrees.
  • Extends ConfigurationBuilder and ConfigurationManager to support building “contextual” configuration sources that require an upstream provider snapshot.
  • Introduces new public API surface (AllowReferences, ConfigurationReferenceBuilder, ConfigurationExpansion) and adds end-to-end tests.

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
src/libraries/Microsoft.Extensions.Configuration/tests/ConfigurationReferenceTests.cs New test coverage for reference resolution, templates, composition, reload behavior, and parsing.
src/libraries/Microsoft.Extensions.Configuration/src/Resources/Strings.resx Adds new user-facing error strings for reference expansion and validation.
src/libraries/Microsoft.Extensions.Configuration/src/ReferenceRule.cs Defines rule semantics (subject + allowed/denied targets) and validates parser output.
src/libraries/Microsoft.Extensions.Configuration/src/ReferenceConfigurationSource.cs Contextual source that requires upstream provider snapshot to build its provider.
src/libraries/Microsoft.Extensions.Configuration/src/ReferenceConfigurationProvider.cs Core implementation: resolves references, mirrors subtrees, composes format expansions, handles reload.
src/libraries/Microsoft.Extensions.Configuration/src/ReferenceConfigurationBuilderExtensions.cs Public builder extension method AllowReferences(...).
src/libraries/Microsoft.Extensions.Configuration/src/KeyPattern.cs Wildcard/doublestar key-pattern matching for subjects/targets.
src/libraries/Microsoft.Extensions.Configuration/src/IContextualConfigurationSource.cs Internal contract to allow sources to build with upstream provider list.
src/libraries/Microsoft.Extensions.Configuration/src/ConfigurationReferenceBuilder.cs Public builder object for declaring rules and customizing the parser.
src/libraries/Microsoft.Extensions.Configuration/src/ConfigurationManager.cs Adds contextual-source dispatch when adding/reloading sources.
src/libraries/Microsoft.Extensions.Configuration/src/ConfigurationExpansion.cs Public struct representing expansion kinds (reference/literal/format) returned by parsers.
src/libraries/Microsoft.Extensions.Configuration/src/ConfigurationBuilder.cs Adds contextual-source dispatch during build.
src/libraries/Microsoft.Extensions.Configuration/ref/Microsoft.Extensions.Configuration.cs Updates public API contract to include the new APIs/types.

Comment thread src/libraries/Microsoft.Extensions.Configuration/src/ConfigurationExpansion.cs Outdated
Comment thread src/libraries/Microsoft.Extensions.Configuration/src/Resources/Strings.resx Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 4 comments.

Comment thread src/libraries/Microsoft.Extensions.Configuration/src/ConfigurationBuilder.cs Outdated
@rosebyte
rosebyte force-pushed the configuration-references branch from 494bd94 to d34a11b Compare July 14, 2026 14:02
Copilot AI review requested due to automatic review settings July 16, 2026 07:49
@rosebyte
rosebyte force-pushed the configuration-references branch from d34a11b to 8082ba9 Compare July 16, 2026 07:49

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.

Comment thread src/libraries/Microsoft.Extensions.Configuration/src/Resources/Strings.resx Outdated
Copilot AI review requested due to automatic review settings July 16, 2026 10:59

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.

Comment thread src/libraries/Microsoft.Extensions.Configuration/src/Resources/Strings.resx Outdated
@tarekgh

tarekgh commented Jul 16, 2026

Copy link
Copy Markdown
Member

@rosebyte could you please get some benchmarks reading configuration especially without references to ensure we don't have any perf regression with configuration reading. Thanks!

@rosebyte

Copy link
Copy Markdown
Member Author

@tarekgh, I'm doing it continuously when iterating the code, with the current approach we are about the same level in general with the only exception of complete miss (where we really have to check all parents down the road). I'm still simplifying the code and getting better results though.

Copilot AI review requested due to automatic review settings July 17, 2026 07:21
@rosebyte
rosebyte force-pushed the configuration-references branch from 89f57b0 to f0f5076 Compare July 17, 2026 07:21

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.

Comment thread src/libraries/Microsoft.Extensions.Configuration/src/ReferenceResolutionCache.cs Outdated
Copilot AI review requested due to automatic review settings August 11, 2026 11:44
@rosebyte
rosebyte force-pushed the configuration-references branch from 129b0bf to 1b4b0f7 Compare August 11, 2026 11:44

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated no new comments.

Suppressed comments (1)

src/libraries/Microsoft.Extensions.Configuration/tests/ConfigurationReferenceTests.cs:677

  • This ordering assertion uses OrderBy(k => k) without an explicit comparer, which makes the test culture-sensitive (string sorting uses the current culture). For deterministic tests, use an ordinal comparer (as you already do elsewhere in this file).
            Assert.Equal(new[] { "Probe", "Target" }, root.GetChildren().Select(c => c.Key).OrderBy(k => k).ToArray());

Copilot AI review requested due to automatic review settings August 12, 2026 04:44

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated no new comments.

Suppressed comments (2)

src/libraries/Microsoft.Extensions.Configuration/src/ReferenceEngine.cs:61

  • if (value is not string raw) is effectively just a null-check since Get returns string?. Using an explicit null check and then assigning raw improves readability and avoids suggesting non-string values are possible here.
            if (value is not string raw)
            {
                return true;
            }

            ReferenceSyntax.Shape shape = ReferenceSyntax.Classify(raw, out int bodyStart, out int bodyLength);

src/libraries/Microsoft.Extensions.Configuration/src/ReferenceEngine.cs:100

  • BuildKey takes an int hops parameter but never uses it, which can trigger unused-parameter analyzers and makes the intent harder to follow. Consider removing hops from the BuildKey signature and updating the call sites (both the call in Read and the recursive BuildKey call) to match.
        private string? BuildKey(IList<IConfigurationProvider> providers, ReadOnlySpan<char> body, string baseKey, int nesting, int hops, ref Trail trail)
        {
            body = body.Trim();

Copilot AI review requested due to automatic review settings August 12, 2026 13:13

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated no new comments.

Suppressed comments (1)

src/libraries/Microsoft.Extensions.Configuration/src/ReferenceEngine.cs:146

  • ThrowMalformedException is annotated [DoesNotReturn] and already throws. Using throw ThrowMalformedException(...) is redundant and makes the control flow harder to follow (the throw is never reached because the helper always throws). Prefer calling the helper directly.
                    else if (c == ReferenceSyntax.BraceClose)
                    {
                        throw ThrowMalformedException(baseKey);
                    }

@rosebyte
rosebyte marked this pull request as ready for review September 30, 2026 13:37
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 4 pipeline(s).
12 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[API Proposal] Add Configuration References

3 participants