153 lines
5.1 KiB
C#
153 lines
5.1 KiB
C#
|
|
using Newtonsoft.Json.Linq;
|
|||
|
|
|
|||
|
|
namespace SWP.Core.Configurations
|
|||
|
|
{
|
|||
|
|
public interface IConfigurationBuilder
|
|||
|
|
{
|
|||
|
|
ConfigurationBuilder AddProvider(IConfigurationProvider provider);
|
|||
|
|
IConfigurationRoot Build();
|
|||
|
|
List<IConfigurationProvider> ConfigurationProviders { get; }
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public class ConfigurationBuilder : IConfigurationBuilder
|
|||
|
|
{
|
|||
|
|
public List<IConfigurationProvider> ConfigurationProviders { get; private set; } = [];
|
|||
|
|
|
|||
|
|
public ConfigurationBuilder AddProvider(IConfigurationProvider provider)
|
|||
|
|
{
|
|||
|
|
((IConfigurationBuilder)this).ConfigurationProviders.Add(provider);
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
public IConfigurationRoot Build()
|
|||
|
|
{
|
|||
|
|
foreach (var provider in ConfigurationProviders)
|
|||
|
|
provider.Build();
|
|||
|
|
//TODO: we need to come up with merge strategy, right now the latest key-path dominates
|
|||
|
|
|
|||
|
|
return new ConfigurationRoot(ConfigurationProviders);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public class Configuration : IConfiguration
|
|||
|
|
{
|
|||
|
|
List<IConfigurationProvider> _providers = [];
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// Implements a string-based indexer for backwards compatibility with Microsoft.Extensions.Configuration.
|
|||
|
|
/// This implementation is marked as obsolete and should be replaced with type-safe alternatives.
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="key">The configuration key to retrieve.</param>
|
|||
|
|
/// <returns>The configuration value for the specified key.</returns>
|
|||
|
|
/// <exception cref="NotSupportedException">Thrown when attempting to set a value, as this operation is not supported.</exception>
|
|||
|
|
[Obsolete("Use type-safe configuration methods instead")]
|
|||
|
|
public string this[string key]
|
|||
|
|
{
|
|||
|
|
get => GetConfiguration(_providers, key);
|
|||
|
|
set => throw new NotSupportedException();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
List<IConfigurationProvider> IConfiguration.ConfigurationProviders
|
|||
|
|
{
|
|||
|
|
get { return _providers; }
|
|||
|
|
set { _providers = value; }
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
internal static string GetConfiguration(IList<IConfigurationProvider> providers, string key)
|
|||
|
|
{
|
|||
|
|
string value = null;
|
|||
|
|
foreach (var provider in providers)
|
|||
|
|
{
|
|||
|
|
var test = provider.Configuration().SelectToken(ConfigurationBinder.NormalizePath(key));
|
|||
|
|
|
|||
|
|
if (test != null)
|
|||
|
|
value = test.ToString();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return value;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public class ConfigurationRoot : Configuration, IConfigurationRoot
|
|||
|
|
{
|
|||
|
|
public ConfigurationRoot(List<IConfigurationProvider> configurationProviders)
|
|||
|
|
{
|
|||
|
|
((IConfiguration)this).ConfigurationProviders = configurationProviders;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
public static class ConfigurationBinder
|
|||
|
|
{
|
|||
|
|
public static string NormalizePath(string path)
|
|||
|
|
{
|
|||
|
|
return path?.Replace(":", ".", StringComparison.Ordinal) ?? string.Empty;
|
|||
|
|
}
|
|||
|
|
public static string GetConnectionString(this IConfigurationRoot configuration, string name)
|
|||
|
|
{
|
|||
|
|
return configuration.GetSection("ConnectionStrings").Get<string>(name);
|
|||
|
|
}
|
|||
|
|
public static IConfigurationSection GetSection(this IConfigurationRoot configuration, string path)
|
|||
|
|
{
|
|||
|
|
JToken value = null;
|
|||
|
|
foreach (var provider in configuration.ConfigurationProviders)
|
|||
|
|
{
|
|||
|
|
var test = provider.Configuration().SelectToken(NormalizePath(path));
|
|||
|
|
|
|||
|
|
if (test != null)
|
|||
|
|
value = test;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return new ConfigurationSection { Path = path, Key = path.Split(':').Last(), Value = value };
|
|||
|
|
}
|
|||
|
|
public static T Get<T>(this IConfigurationRoot configuration, string path)
|
|||
|
|
{
|
|||
|
|
JToken value = null;
|
|||
|
|
foreach (var provider in configuration.ConfigurationProviders)
|
|||
|
|
{
|
|||
|
|
var test = provider.Configuration().SelectToken(NormalizePath(path));
|
|||
|
|
|
|||
|
|
if (test != null)
|
|||
|
|
value = test;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return value.ToObject<T>();
|
|||
|
|
}
|
|||
|
|
public static T Get<T>(this IConfigurationSection configuration, string path)
|
|||
|
|
{
|
|||
|
|
var value = configuration.Value.SelectToken(NormalizePath(path)).ToObject<T>();
|
|||
|
|
return value;
|
|||
|
|
}
|
|||
|
|
public static T ToObject<T>(this IConfigurationSection configuration)
|
|||
|
|
{
|
|||
|
|
var value = configuration.Value.ToObject<T>();
|
|||
|
|
return value;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
[Obsolete("Use ToObject")]
|
|||
|
|
public static T Get<T>(this IConfigurationSection configuration)
|
|||
|
|
{
|
|||
|
|
return configuration.Value.ToObject<T>();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
public interface IConfigurationProvider
|
|||
|
|
{
|
|||
|
|
void Build();
|
|||
|
|
JObject Configuration();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public class ConfigurationSection : IConfigurationSection
|
|||
|
|
{
|
|||
|
|
public required string Path { get; set; }
|
|||
|
|
public required string Key { get; set; }
|
|||
|
|
|
|||
|
|
public required JToken Value { get; set; }
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
public interface IConfigurationSection
|
|||
|
|
{
|
|||
|
|
string Path { get; }
|
|||
|
|
string Key { get; }
|
|||
|
|
JToken Value { get; set; }
|
|||
|
|
}
|
|||
|
|
}
|