using EasyDevCore.Common; using EasyDevCore.Configuration.Configuration; using Microsoft.Extensions.Configuration; using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; using System.Xml.Linq; namespace EasyDevCore.Configuration { /// /// /// public static class ConfigurationHelper { /// /// 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; } } /// /// Gets the application setting constants. /// /// The configuration root. /// public static Dictionary GetAppSettingConstants(this IConfigurationRoot configurationRoot) { var appContantsSection = configurationRoot.GetSection("AppSetting:Constants"); var envContantsSection = appContantsSection.GetSection("HOST-ENVIROMENT-VARIABLE"); Dictionary result = new(); foreach (var kp in appContantsSection.GetChildren().Where(kp => !kp.Key.Equals("HOST-ENVIROMENT-VARIABLE", StringComparison.InvariantCultureIgnoreCase))) { result[kp.Key] = kp.Value; } foreach (var kp in envContantsSection.GetChildren()) { bool isPrefer = kp.Key.StartsWith("!"); string key = isPrefer ? kp.Key.Substring(1) : kp.Key; string envValue = null; if (!result.ContainsKey(key) || isPrefer) { envValue = Environment.GetEnvironmentVariable(kp.Value); } if (envValue != null) { result[key] = envValue; } } return result; } /// /// Maps the application setting contants. /// /// The builder. /// public static IConfigurationBuilder MapAppSettingContants(this IConfigurationBuilder builder) { var root = (builder as IConfigurationRoot); var appContantsSection = root.GetSection("AppSettings:Constants"); Dictionary constValues = new(); foreach (var kp in appContantsSection.GetChildren().Where(x => !string.IsNullOrWhiteSpace(x.Value))) { constValues[kp.Key] = kp.Value; } List placeHolders = new(); foreach (var kp in root.GetAllChildren().Where(x => !string.IsNullOrWhiteSpace(x.Value) && x.Value.Contains("{{") && x.Value.Contains("}}"))) { placeHolders.Clear(); kp.Value.RegexGroupMatch(@"\{\{(?[^{}].*?)\}\}", (g) => { if(constValues.ContainsKey(g.Value)) { placeHolders.Add(g.Value); } }); foreach(var p in placeHolders) { kp.Value = kp.Value.Replace("{{" + p + "}}", constValues[p]); } } return builder; } /// /// Gets the application setting constants. /// /// The configuration root. /// public static Dictionary GetAppSettingEnvConstants(this IConfigurationRoot configurationRoot) { Dictionary result = new Dictionary(); foreach (var kp in configurationRoot.GetSection("AppSetting:Constants:HOST-ENVIROMENT-VARIABLE").GetChildren()) { result.Add(kp.Key, kp.Value); } return result; } /// /// Gets the configuration section. /// /// The configuration. /// Name of the section. /// public static IConfigurationSection GetConfigMapEnvVariableSection(this IConfiguration configuration, string sectionName) => new EasyConfigurationSection(configuration.GetSection(sectionName)); /// /// Binds the configuration value. /// /// The type of the model. /// The section. /// Name of the section. /// public static TModel BindConfigEnvVariable(this IConfiguration section, string sectionName) where TModel : class { return section.GetConfigMapEnvVariableSection(sectionName).Bind(); } private static string GetEnvironmentVariable(string key) { return Environment.GetEnvironmentVariable(key, EnvironmentVariableTarget.Process) ?? Environment.GetEnvironmentVariable(key, EnvironmentVariableTarget.User) ?? Environment.GetEnvironmentVariable(key, EnvironmentVariableTarget.Machine); } /// /// Translates the configuration value with enviroment macro. /// /// The section. /// The value. /// The default value. /// public static T ResolveConfigVariable(this IConfiguration section, string value, T defaultValue = default(T)) { var root = section.GetConfiguationRoot(); var appContantsSection = root.GetSection("AppSettings:Constants"); var envContantsSection = appContantsSection.GetSection("HOST-ENVIROMENT-VARIABLE"); Dictionary appContants = new(); value.RegexGroupMatch(@"\{\{(.*?)\}\}", (m) => { try { string appValue = appContantsSection.GetValue(m.Value); string envValueKey = envContantsSection.GetValue(m.Value); string preferEnvKey = envContantsSection.GetValue("!" + m.Value); string replaceValue = (preferEnvKey == null ? null : GetEnvironmentVariable(preferEnvKey)) ?? appValue ?? (envValueKey == null ? null : GetEnvironmentVariable(envValueKey)); if (replaceValue != null) { appContants[m.Value] = replaceValue; } } catch { } }); foreach (var kp in appContants) { value = value.Replace(kp.Key, kp.Value); } if (defaultValue == null) { return value.ConvertTo(); } else { return value.ConvertTo(defaultValue); } } /// /// Gets configuration value and auto substitute with constants. /// /// /// The section. /// The key. /// The default value. /// public static T GetConfigMapVariable(this IConfiguration section, string key, T defaultValue = default(T)) { return ResolveConfigVariable(section, section.GetSection(key).Value, defaultValue); } /// /// 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; } } }