|
// 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 System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
namespace Microsoft.Extensions.Configuration
{
/// <summary>
/// Provides extension methods for configuration classes.
/// </summary>
public static class ConfigurationExtensions
{
/// <summary>
/// Adds a new configuration source.
/// </summary>
/// <param name="builder">The builder to add to.</param>
/// <param name="configureSource">Configures the source secrets.</param>
/// <returns>The <see cref="IConfigurationBuilder"/>.</returns>
public static IConfigurationBuilder Add<TSource>(this IConfigurationBuilder builder, Action<TSource>? configureSource) where TSource : IConfigurationSource, new()
{
var source = new TSource();
configureSource?.Invoke(source);
return builder.Add(source);
}
/// <summary>
/// Gets the specified connection string from the specified configuration.
/// Shorthand for <c>GetSection("ConnectionStrings")[name]</c>.
/// </summary>
/// <param name="configuration">The configuration to enumerate.</param>
/// <param name="name">The connection string key.</param>
/// <returns>The connection string.</returns>
public static string? GetConnectionString(this IConfiguration configuration, string name)
{
return configuration?.GetSection("ConnectionStrings")[name];
}
/// <summary>
/// Get the enumeration of key value pairs within the <see cref="IConfiguration" />
/// </summary>
/// <param name="configuration">The configuration to enumerate.</param>
/// <returns>An enumeration of key value pairs.</returns>
public static IEnumerable<KeyValuePair<string, string?>> AsEnumerable(this IConfiguration configuration) => configuration.AsEnumerable(makePathsRelative: false);
/// <summary>
/// Get the enumeration of key value pairs within the <see cref="IConfiguration" />
/// </summary>
/// <param name="configuration">The configuration to enumerate.</param>
/// <param name="makePathsRelative"><see langword="true" /> to trim the current configuration's path from the front of the returned child keys.</param>
/// <returns>An enumeration of key value pairs.</returns>
public static IEnumerable<KeyValuePair<string, string?>> AsEnumerable(this IConfiguration configuration, bool makePathsRelative)
{
var stack = new Stack<IConfiguration>();
stack.Push(configuration);
int prefixLength = (makePathsRelative && configuration is IConfigurationSection rootSection) ? rootSection.Path.Length + 1 : 0;
while (stack.Count > 0)
{
IConfiguration config = stack.Pop();
// Don't include the sections value if we are removing paths, since it will be an empty key
if (config is IConfigurationSection section && (!makePathsRelative || config != configuration))
{
yield return new KeyValuePair<string, string?>(section.Path.Substring(prefixLength), section.Value);
}
foreach (IConfigurationSection child in config.GetChildren())
{
stack.Push(child);
}
}
}
/// <summary>
/// Determines whether the section has a <see cref="IConfigurationSection.Value"/> or has children.
/// </summary>
/// <param name="section">The section to enumerate.</param>
/// <returns><see langword="true" /> if the section has values or children; otherwise, <see langword="false" />.</returns>
public static bool Exists([NotNullWhen(true)] this IConfigurationSection? section)
{
if (section == null)
{
return false;
}
return section.Value != null || section.GetChildren().Any();
}
/// <summary>
/// Gets a configuration subsection with the specified key.
/// </summary>
/// <param name="configuration">The configuration to enumerate.</param>
/// <param name="key">The key of the configuration section.</param>
/// <returns>The <see cref="IConfigurationSection"/>.</returns>
/// <remarks>
/// If no matching sub-section is found with the specified key, an exception is raised.
/// </remarks>
/// <exception cref="System.InvalidOperationException">There is no section with key <paramref name="key"/>.</exception>
public static IConfigurationSection GetRequiredSection(this IConfiguration configuration, string key)
{
ThrowHelper.ThrowIfNull(configuration);
IConfigurationSection section = configuration.GetSection(key);
if (section.Exists())
{
return section;
}
throw new InvalidOperationException(SR.Format(SR.InvalidSectionName, key));
}
}
}
|