using EasyDevCore.Common;
using EasyDevCore.Configuration.Configuration;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace EasyDevCore.Configuration
{
///
///
///
public static class ConfigurationHelper
{
///
/// Adds the constant variables (constant declare in "AppSettings:Constants" section).
///
/// The builder.
/// The configuration root.
///
public static IConfigurationBuilder AddConstantVariables(this IConfigurationBuilder builder, IConfigurationRoot configurationRoot = null)
{
builder.Add(new SubstitutingConfigurationSource(configurationRoot ?? builder.Build(), "AppSettings:Constants"));
return builder;
}
///
/// Adds the decrypting data.
///
/// The builder.
/// The decrypt function.
/// The configuration root.
///
public static IConfigurationBuilder AddDecryptingData(this IConfigurationBuilder builder, Func decryptFunc, IConfigurationRoot configurationRoot = null)
{
builder.Add(new ProtectDataConfigurationSource(configurationRoot ?? builder.Build(), encryptFunc: null, decryptFunc));
return builder;
}
///
/// Adds the protect data.
///
/// The builder.
/// The encrypt function.
/// The decrypt function.
/// The configuration root.
///
public static IConfigurationBuilder AddProtectData(this IConfigurationBuilder builder, Func encryptFunc, Func decryptFunc, IConfigurationRoot configurationRoot = null)
{
builder.Add(new ProtectDataConfigurationSource(configurationRoot ?? builder.Build(), encryptFunc, decryptFunc));
return builder;
}
///
/// Gets the configuation root.
///
/// The section.
///
public static IConfigurationRoot GetConfiguationRoot(this IConfiguration section)
{
if (section is IConfigurationRoot)
{
return (IConfigurationRoot)section;
}
else
{
var fieldInfo = section.GetType().GetField("_root", BindingFlags.NonPublic | BindingFlags.Instance);
var root = fieldInfo.GetValue(section);
return (IConfigurationRoot)root;
}
}
///
/// Binds the specified section.
///
///
/// The section.
///
///
///
public static T Bind(this IConfigurationSection section)
{
try
{
if (section.Value != null)
return section.Value.ConvertTo();
if (typeof(T).HasInterface()
&& !typeof(T).HasInterface())
{
var values = section.GetChildren().Map(GetValue);
return values.ConvertTo();
}
}
catch (Exception ex)
{
var message = $"The {section.Key} setting had an invalid format. " +
$"The value \"{section.Value}\" could not be cast to type {typeof(T).FullName}";
throw new ConfigurationErrorsException(message, ex);
}
try
{
var to = typeof(T).CreateInstance();
section.Bind(to);
return (T)to;
}
catch (InvalidOperationException ex)
{
throw new ConfigurationErrorsException(ex.Message, ex);
}
}
///
/// Binds the specified section name.
///
///
/// The configuration.
/// Name of the section.
///
public static T Bind(this IConfiguration config, string sectionName = null) => Bind(config.GetSection(sectionName ?? typeof(T).Name));
///
/// Existses the specified key.
///
/// The section.
/// The key.
///
public static bool Exists(this IConfigurationSection section, string key) => section.GetChildren().Any(x => x.Key == key) || section.GetSection(key).Exists();
///
/// Existses the specified key.
///
/// The configuration.
/// The key.
///
public static bool Exists(this IConfiguration config, string key) => config.GetChildren().Any(x => x.Key == key) || config.GetSection(key).Exists();
private static void GetAllChildren(List list, IConfiguration config)
{
foreach(var item in config.GetChildren())
{
if (item is IConfigurationSection) list.Add(item);
GetAllChildren(list, item);
}
}
///
/// Gets all children.
///
/// The configuration.
///
public static IEnumerable GetAllChildren(this IConfiguration configuration)
{
List list = new();
GetAllChildren(list, configuration);
return list;
}
/// Gets the value.
/// The section.
///
///
///
static object GetValue(this IConfigurationSection section)
{
if (section == null)
return null;
if (section.Value != null)
return section.Value;
var children = section.GetChildren();
var first = children.FirstOrDefault();
if (first == null)
return null;
if (first.Key == "0")
{
var to = children.Select(GetValue).ToList();
if (to.Count > 0)
return to;
}
else
{
var to = new Dictionary();
foreach (var child in children)
{
to[child.Key] = GetValue(child);
}
if (to.Count > 0)
return to;
}
return null;
}
}
}