Migrates connection strings to new database host Removes unnecessary code and improves configuration handling Enhances test coverage and adds random word generation Updates telemetry and command handling patterns
157 lines
5.4 KiB
C#
157 lines
5.4 KiB
C#
using Newtonsoft.Json.Linq;
|
|
namespace PlanTempus.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, bool optional = true)
|
|
{
|
|
JToken value = null;
|
|
foreach (var provider in configuration.ConfigurationProviders)
|
|
{
|
|
var test = provider.Configuration().SelectToken(NormalizePath(path));
|
|
|
|
if (test != null)
|
|
value = test;
|
|
}
|
|
if(value is null && !optional)
|
|
throw new Exceptions.ConfigurationException($"Path not found in configuration, path: {path}");
|
|
if (value is null)
|
|
return default;
|
|
|
|
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; }
|
|
}
|
|
}
|