Add Configuration references - #129734
Add Configuration references#129734rosebyte wants to merge 11 commits into
Conversation
|
Tagging subscribers to this area: @dotnet/area-extensions-configuration |
There was a problem hiding this comment.
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
ConfigurationBuilderandConfigurationManagerto 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. |
9325454 to
494bd94
Compare
494bd94 to
d34a11b
Compare
d34a11b to
8082ba9
Compare
|
@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! |
|
@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. |
89f57b0 to
f0f5076
Compare
129b0bf to
1b4b0f7
Compare
There was a problem hiding this comment.
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());
There was a problem hiding this comment.
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 sinceGetreturnsstring?. Using an explicitnullcheck and then assigningrawimproves 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
BuildKeytakes anint hopsparameter but never uses it, which can trigger unused-parameter analyzers and makes the intent harder to follow. Consider removinghopsfrom theBuildKeysignature and updating the call sites (both the call inReadand the recursiveBuildKeycall) to match.
private string? BuildKey(IList<IConfigurationProvider> providers, ReadOnlySpan<char> body, string baseKey, int nesting, int hops, ref Trail trail)
{
body = body.Trim();
There was a problem hiding this comment.
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
ThrowMalformedExceptionis annotated[DoesNotReturn]and already throws. Usingthrow ThrowMalformedException(...)is redundant and makes the control flow harder to follow (thethrowis never reached because the helper always throws). Prefer calling the helper directly.
else if (c == ReferenceSyntax.BraceClose)
{
throw ThrowMalformedException(baseKey);
}
|
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. |
Fixes #127852