ConfigurationHelper.cs 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. using EasyDevCore.Common;
  2. using EasyDevCore.Configuration.Configuration;
  3. using Microsoft.Extensions.Configuration;
  4. using System;
  5. using System.Collections;
  6. using System.Collections.Generic;
  7. using System.Diagnostics;
  8. using System.Linq;
  9. using System.Reflection;
  10. using System.Runtime.InteropServices;
  11. using System.Text;
  12. using System.Threading.Tasks;
  13. using System.Xml.Linq;
  14. namespace EasyDevCore.Configuration
  15. {
  16. /// <summary>
  17. ///
  18. /// </summary>
  19. public static class ConfigurationHelper
  20. {
  21. /// <summary>
  22. /// Adds the constant variables (constant declare in "AppSettings:Constants" section).
  23. /// </summary>
  24. /// <param name="builder">The builder.</param>
  25. /// <param name="configurationRoot">The configuration root.</param>
  26. /// <returns></returns>
  27. public static IConfigurationBuilder AddConstantVariables(this IConfigurationBuilder builder, IConfigurationRoot configurationRoot = null)
  28. {
  29. builder.Add(new SubstitutingConfigurationSource(configurationRoot ?? builder.Build(), "AppSettings:Constants"));
  30. return builder;
  31. }
  32. /// <summary>
  33. /// Adds the decrypting data.
  34. /// </summary>
  35. /// <param name="builder">The builder.</param>
  36. /// <param name="decryptFunc">The decrypt function.</param>
  37. /// <param name="configurationRoot">The configuration root.</param>
  38. /// <returns></returns>
  39. public static IConfigurationBuilder AddDecryptingData(this IConfigurationBuilder builder, Func<string, string, string> decryptFunc, IConfigurationRoot configurationRoot = null)
  40. {
  41. builder.Add(new ProtectDataConfigurationSource(configurationRoot ?? builder.Build(), encryptFunc: null, decryptFunc));
  42. return builder;
  43. }
  44. /// <summary>
  45. /// Adds the protect data.
  46. /// </summary>
  47. /// <param name="builder">The builder.</param>
  48. /// <param name="encryptFunc">The encrypt function.</param>
  49. /// <param name="decryptFunc">The decrypt function.</param>
  50. /// <param name="configurationRoot">The configuration root.</param>
  51. /// <returns></returns>
  52. public static IConfigurationBuilder AddProtectData(this IConfigurationBuilder builder, Func<string, string, string> encryptFunc, Func<string, string, string> decryptFunc, IConfigurationRoot configurationRoot = null)
  53. {
  54. builder.Add(new ProtectDataConfigurationSource(configurationRoot ?? builder.Build(), encryptFunc, decryptFunc));
  55. return builder;
  56. }
  57. /// <summary>
  58. /// Gets the configuation root.
  59. /// </summary>
  60. /// <param name="section">The section.</param>
  61. /// <returns></returns>
  62. public static IConfigurationRoot GetConfiguationRoot(this IConfiguration section)
  63. {
  64. if (section is IConfigurationRoot)
  65. {
  66. return (IConfigurationRoot)section;
  67. }
  68. else
  69. {
  70. var fieldInfo = section.GetType().GetField("_root", BindingFlags.NonPublic | BindingFlags.Instance);
  71. var root = fieldInfo.GetValue(section);
  72. return (IConfigurationRoot)root;
  73. }
  74. }
  75. /// <summary>
  76. /// Binds the specified section.
  77. /// </summary>
  78. /// <typeparam name="T"></typeparam>
  79. /// <param name="section">The section.</param>
  80. /// <returns></returns>
  81. /// <exception cref="ConfigurationErrorsException">
  82. /// </exception>
  83. public static T Bind<T>(this IConfigurationSection section)
  84. {
  85. try
  86. {
  87. if (section.Value != null)
  88. return section.Value.ConvertTo<T>();
  89. if (typeof(T).HasInterface<IEnumerable>()
  90. && !typeof(T).HasInterface<IDictionary>())
  91. {
  92. var values = section.GetChildren().Map(GetValue);
  93. return values.ConvertTo<T>();
  94. }
  95. }
  96. catch (Exception ex)
  97. {
  98. var message = $"The {section.Key} setting had an invalid format. " +
  99. $"The value \"{section.Value}\" could not be cast to type {typeof(T).FullName}";
  100. throw new ConfigurationErrorsException(message, ex);
  101. }
  102. try
  103. {
  104. var to = typeof(T).CreateInstance();
  105. section.Bind(to);
  106. return (T)to;
  107. }
  108. catch (InvalidOperationException ex)
  109. {
  110. throw new ConfigurationErrorsException(ex.Message, ex);
  111. }
  112. }
  113. /// <summary>
  114. /// Binds the specified section name.
  115. /// </summary>
  116. /// <typeparam name="T"></typeparam>
  117. /// <param name="config">The configuration.</param>
  118. /// <param name="sectionName">Name of the section.</param>
  119. /// <returns></returns>
  120. public static T Bind<T>(this IConfiguration config, string sectionName = null) => Bind<T>(config.GetSection(sectionName ?? typeof(T).Name));
  121. /// <summary>
  122. /// Existses the specified key.
  123. /// </summary>
  124. /// <param name="section">The section.</param>
  125. /// <param name="key">The key.</param>
  126. /// <returns></returns>
  127. public static bool Exists(this IConfigurationSection section, string key) => section.GetChildren().Any(x => x.Key == key) || section.GetSection(key).Exists();
  128. /// <summary>
  129. /// Existses the specified key.
  130. /// </summary>
  131. /// <param name="config">The configuration.</param>
  132. /// <param name="key">The key.</param>
  133. /// <returns></returns>
  134. public static bool Exists(this IConfiguration config, string key) => config.GetChildren().Any(x => x.Key == key) || config.GetSection(key).Exists();
  135. private static void GetAllChildren(List<IConfigurationSection> list, IConfiguration config)
  136. {
  137. foreach(var item in config.GetChildren())
  138. {
  139. if (item is IConfigurationSection) list.Add(item);
  140. GetAllChildren(list, item);
  141. }
  142. }
  143. /// <summary>
  144. /// Gets all children.
  145. /// </summary>
  146. /// <param name="configuration">The configuration.</param>
  147. /// <returns></returns>
  148. public static IEnumerable<IConfigurationSection> GetAllChildren(this IConfiguration configuration)
  149. {
  150. List<IConfigurationSection> list = new();
  151. GetAllChildren(list, configuration);
  152. return list;
  153. }
  154. /// <summary>Gets the value.</summary>
  155. /// <param name="section">The section.</param>
  156. /// <returns>
  157. /// <br />
  158. /// </returns>
  159. static object GetValue(this IConfigurationSection section)
  160. {
  161. if (section == null)
  162. return null;
  163. if (section.Value != null)
  164. return section.Value;
  165. var children = section.GetChildren();
  166. var first = children.FirstOrDefault();
  167. if (first == null)
  168. return null;
  169. if (first.Key == "0")
  170. {
  171. var to = children.Select(GetValue).ToList();
  172. if (to.Count > 0)
  173. return to;
  174. }
  175. else
  176. {
  177. var to = new Dictionary<string, object>();
  178. foreach (var child in children)
  179. {
  180. to[child.Key] = GetValue(child);
  181. }
  182. if (to.Count > 0)
  183. return to;
  184. }
  185. return null;
  186. }
  187. }
  188. }