Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@

namespace Microsoft.Extensions.Configuration
{
public sealed partial class ConfigurationReferenceBuilder
{
internal ConfigurationReferenceBuilder() { }
public Microsoft.Extensions.Configuration.ConfigurationReferenceBuilder Allow(string subject, string target, params string[] additionalTargets) { throw null; }
public Microsoft.Extensions.Configuration.ConfigurationReferenceBuilder Deny(string subject, string target, params string[] additionalTargets) { throw null; }
Comment on lines +9 to +13
public System.Func<Microsoft.Extensions.Configuration.ConfigurationReferenceContext, Microsoft.Extensions.Configuration.ConfigurationExpansion?> Parser { get { throw null; } set { } }
}
public static partial class ChainedBuilderExtensions
{
public static Microsoft.Extensions.Configuration.IConfigurationBuilder AddConfiguration(this Microsoft.Extensions.Configuration.IConfigurationBuilder configurationBuilder, Microsoft.Extensions.Configuration.IConfiguration config) { throw null; }
Expand Down Expand Up @@ -107,6 +114,29 @@ public static partial class MemoryConfigurationBuilderExtensions
public static Microsoft.Extensions.Configuration.IConfigurationBuilder AddInMemoryCollection(this Microsoft.Extensions.Configuration.IConfigurationBuilder configurationBuilder) { throw null; }
public static Microsoft.Extensions.Configuration.IConfigurationBuilder AddInMemoryCollection(this Microsoft.Extensions.Configuration.IConfigurationBuilder configurationBuilder, System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, string?>>? initialData) { throw null; }
}
public static partial class ReferenceConfigurationBuilderExtensions
{
public static Microsoft.Extensions.Configuration.IConfigurationBuilder AllowReferences(this Microsoft.Extensions.Configuration.IConfigurationBuilder builder, System.Action<Microsoft.Extensions.Configuration.ConfigurationReferenceBuilder> configure) { throw null; }
}
public readonly partial struct ConfigurationExpansion
{
private readonly object _dummy;
private readonly int _dummyPrimitive;
public Microsoft.Extensions.Primitives.StringValues Keys { get { throw null; } }
public string? Template { get { throw null; } }
public static Microsoft.Extensions.Configuration.ConfigurationExpansion Format(string template, string key) { throw null; }
public static Microsoft.Extensions.Configuration.ConfigurationExpansion Format(string template, params string[] keys) { throw null; }
public static Microsoft.Extensions.Configuration.ConfigurationExpansion Literal(string? value) { throw null; }
public static Microsoft.Extensions.Configuration.ConfigurationExpansion Reference(string key) { throw null; }
}
public readonly partial struct ConfigurationReferenceContext
{
private readonly object _dummy;
private readonly int _dummyPrimitive;
public string Key { get { throw null; } }
public System.Collections.Generic.IReadOnlyList<Microsoft.Extensions.Configuration.IConfigurationProvider> Providers { get { throw null; } }
public string Value { get { throw null; } }
}
public abstract partial class StreamConfigurationProvider : Microsoft.Extensions.Configuration.ConfigurationProvider
{
public StreamConfigurationProvider(Microsoft.Extensions.Configuration.StreamConfigurationSource source) { }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,14 @@ public IConfigurationBuilder Add(IConfigurationSource source)
/// <returns>An <see cref="IConfigurationRoot"/> with keys and values from the registered providers.</returns>
public IConfigurationRoot Build()
{
var providers = new List<IConfigurationProvider>();
var providers = new List<IConfigurationProvider>(_sources.Count);
foreach (IConfigurationSource source in _sources)
{
IConfigurationProvider provider = source.Build(this);
providers.Add(provider);
providers.Add(source is IContextualConfigurationSource cs
? cs.Build(this, providers.ToArray())
: source.Build(this));
}

return new ConfigurationRoot(providers);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using Microsoft.Extensions.Primitives;

namespace Microsoft.Extensions.Configuration
{
/// <summary>
/// Describes how the framework expands a configuration value into its effective value: a redirect to another
/// key (a reference), a verbatim literal, or a formatted composition. An expansion is produced by a parser
/// (see <see cref="ConfigurationReferenceBuilder.Parser"/>) and consumed by the configuration reference
/// machinery; it never reads configuration itself, it only names the keys the framework should resolve.
/// </summary>
public readonly struct ConfigurationExpansion
{
private ConfigurationExpansion(string? template, StringValues keys)
{
Template = template;
Keys = keys;
}

/// <summary>
/// Creates an expansion that passes through the value of <paramref name="key"/>. If the target is a leaf, the
/// subject takes its scalar value; if it is a section, the subject mirrors the whole subtree.
/// </summary>
/// <param name="key">The target key to resolve and pass through.</param>
public static ConfigurationExpansion Reference(string key)
{
ArgumentNullException.ThrowIfNull(key);
return new ConfigurationExpansion(template: null, new StringValues(key));
}

/// <summary>
/// Creates an expansion whose resolved value is <paramref name="value"/> verbatim. The value is taken as-is and is
/// never passed through <see cref="string.Format(string, object[])"/>, so braces are safe.
/// </summary>
/// <param name="value">The literal value the subject resolves to, or <see langword="null"/> for no value.</param>
public static ConfigurationExpansion Literal(string? value) => new ConfigurationExpansion(value, StringValues.Empty);

/// <summary>
/// Creates an expansion whose resolved value is <see cref="string.Format(string, object[])"/> applied to
/// <paramref name="template"/> with the resolved value of <paramref name="key"/> as the single argument.
/// </summary>
/// <param name="template">A composite format string (for example <c>"Server={0}"</c>).</param>
/// <param name="key">The target key whose resolved value fills the placeholder.</param>
public static ConfigurationExpansion Format(string template, string key)
{
ArgumentNullException.ThrowIfNull(template);
ArgumentNullException.ThrowIfNull(key);
return new ConfigurationExpansion(template, new StringValues(key));
}

/// <summary>
/// Creates an expansion whose resolved value is <see cref="string.Format(string, object[])"/> applied to
/// <paramref name="template"/> with the resolved values of <paramref name="keys"/> as arguments.
/// </summary>
/// <param name="template">A composite format string (for example <c>"Server={0};Port={1}"</c>).</param>
/// <param name="keys">The target keys whose resolved values fill the placeholders, in order.</param>
/// <remarks>If no keys are supplied, the template is taken verbatim, without a formatting pass.</remarks>
public static ConfigurationExpansion Format(string template, params string[] keys)
{
ArgumentNullException.ThrowIfNull(template);
ArgumentNullException.ThrowIfNull(keys);
return new ConfigurationExpansion(template, keys.Length switch
{
0 => StringValues.Empty,
1 => new StringValues(keys[0]),
_ => new StringValues(keys),
});
}

/// <summary>
/// Gets the literal value (for an expansion created by <see cref="Literal"/>) or the composite format
/// template (for one created by <see cref="Format(string, string[])"/>), or <see langword="null"/> for a
/// reference created by <see cref="Reference"/>.
/// </summary>
public string? Template { get; }

/// <summary>
/// Gets the keys this expansion refers to: empty for a verbatim literal, the single key for a reference or
/// single-key format, or several keys for a multi-key format.
/// </summary>
public StringValues Keys { get; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,22 @@ private void RaiseChanged()
// Don't rebuild and reload all providers in the common case when a source is simply added to the IList.
private void AddSource(IConfigurationSource source)
{
IConfigurationProvider provider = source.Build(this);
IConfigurationProvider provider;
if (source is IContextualConfigurationSource contextual)
{
// The contextual source needs an upstream snapshot taken at its declaration
// point; whatever providers exist now become its previousProviders.
IConfigurationProvider[] upstream;
using (ReferenceCountedProviders existing = _providerManager.GetReference())
{
upstream = existing.Providers.ToArray();
}
provider = contextual.Build(this, upstream);
}
else
{
provider = source.Build(this);
}

provider.Load();
_changeTokenRegistrations.Add(ChangeToken.OnChange(provider.GetReloadToken, RaiseChanged));
Expand All @@ -143,7 +158,9 @@ private void ReloadSources()

foreach (IConfigurationSource source in _sources)
{
newProvidersList.Add(source.Build(this));
newProvidersList.Add(source is IContextualConfigurationSource cs
? cs.Build(this, newProvidersList.ToArray())
: source.Build(this));
}

foreach (IConfigurationProvider p in newProvidersList)
Expand Down
Loading
Loading