自定义配置节与配置节的读取

一、引子

你是否也遇到过这样的问题:项目很多配置都写到了App.Config或Web.Config的AppSettings内,每个人都加了几条,到最后囤积了大量的配置,分不清哪个是有用的、哪个是没用的了。(即便加了相关注释,也是乱的可以)

 1   <appSettings>
 2     <!--是否抛出异常-->
 3     <add key="HasException" value="true" />
 4     <add key="Mess**********_Enable" value="true" />
 5     <add key="Mess**********_CorpCode" value="" />
 6     <add key="Mess**********_Url" value="" />
 7     <add key="Mess**********_Account" value="" />
 8     <add key="Mess**********_AuthKey" value="" />
 9     <add key="Mess**********_CGID" value="" />
10     <add key="Mess**********_MaxNumberPerHour" value="" />
11     <add key="Mess**********_Signature" value="" />
12     <add key="Mess**********__Enable" value="true" />
13     <add key="JPush**********Key" value="**********" />
14     <add key="JPush**********Secret" value="**********" />
15     <add key="Aud**********Hosts" value="127.0.0.1:1000" />
16     <!--true开启 false 关闭-->
17     <add key="Mess**********_Enable" value="true" />
18     <!--key-->
19     <add key="Baidu**********Key" value="**********" />
20     <add key="Baidu**********Secret" value="**********" />
21     <!--微信开发者 AppId,Secret和Token-->
22     <add key="AppId" value="**********" />
23     <add key="Secret" value="**********" />
24     <add key="Token" value="**********" />
25     <!--证书文件路径(退款用)-->
26     <add key="CertPath" value="E:certapiclient_cert.pem" />
27     <!--App证书文件路径(退款用)-->
28     <add key="AppCertPath" value="E:cert**********.pfx" />
29   </appSettings>

那么问题来了,怎么解决呢?  

二、方案

 将同类、同项目、同模块的配置放到自定义配置节下,统一管理、读取,(可能并不是很好的解决方案,不喜勿喷)。如:

 1 <configuration>
 2   <configSections>
 3     <!--自定义Section声明-->
 4     <!--name:自定义节点名称-->
 5     <!--type:读取配置信息类的命名空间,所在程序集-->
 6     <section name="AssemblyInfo" type="Hetring.ConfigReader.SectionReader,Hetring.ConfigReader" requirePermission="false"></section>
 7   </configSections>
 8 
 9   <!--名称同声明的name-->
10   <AssemblyInfo>
11     <add key="Name" value="Hetring.ConfigReader" />
12     <add key="Version" value="1.0" />
13     <add key="Description" value="This is description." />
14   </AssemblyInfo>
15 </configuration>
三、代码

自定义配置节处理程序,需继承System.Configuration.IConfigurationSectionHandler接口,并实现object Create(object parent, object configContext, XmlNode section)方法:

 1     public class SectionReader : IConfigurationSectionHandler
 2     {
 3         public object Create(object parent, object configContext, System.Xml.XmlNode section)
 4         {
 5             lock (typeof(SectionReader))
 6             {
 7                 Hashtable sectionSetting = new Hashtable();//存放配置信息,也可用Dictionary<string,string>
 8 
 9                 foreach (XmlNode node in section.ChildNodes)
10                 {
11                     if (node.NodeType == XmlNodeType.Element && node.Name == "add")
12                     {
13                         var key = node.Attributes["key"].Value;
14                         var value = node.Attributes["value"].Value;
15                         sectionSetting.Add(key, value);//放入hashtable中
16                     }
17                 }
18 
19                 return sectionSetting;
20             }
21         }
22     } 

 读取配置节时,需要用到System.Configuration.ConfigurationManager.GetSection(SectionName)方法,获取到的是object类型对象,而我们定义的处理程序返回的是Hashtable,直接转换即可:

 1     public class AssemblyInfoConfig
 2     {
 3         /// <summary>
 4         /// Section名称
 5         /// </summary>
 6         private static string SectionName = "AssemblyInfo";
 7 
 8         private static Hashtable _settings { getset; }
 9 
10         protected static Hashtable SectionSettings
11         {
12             get
13             {
14                 //当无配置时,ConfigurationManager.GetSection()会返回null,这里强制创建一个hashtable,防止空引用
15                 if (_settings == null)
16                     _settings = (ConfigurationManager.GetSection(SectionName) as Hashtable) ?? new Hashtable();
17 
18                 return _settings;
19             }
20         }
21 
22         public static string Name
23         {
24             get
25             {
26                 return ObjectToString(SectionSettings["Name"]);
27             }
28         }
29 
30         public static string Version
31         {
32             get
33             {
34                 return ObjectToString(SectionSettings["Version"]);
35             }
36         }
37 
38         public static string Description
39         {
40             get
41             {
42                 return ObjectToString(SectionSettings["Description"]);
43             }
44         }
45 
46         #region 私有方法
47 
48         /// <summary>
49         /// 将Object转换为非null字符串
50         /// </summary>
51         /// <param name="value">待转换Object</param>
52         /// <returns>不为空的字符串(value为null,返回空字符串)</returns>
53         private static string ObjectToString(object value)
54         {
55             if (value == null)
56                 return string.Empty;
57 
58             return value.ToString();
59         }
60 
61         #endregion
62     }
四、调用

 写了个控制台测试下:

 1     class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             Console.WriteLine("Name:" + AssemblyInfoConfig.Name);
 6             Console.WriteLine("Version:" + AssemblyInfoConfig.Version);
 7             Console.WriteLine("Description:" + AssemblyInfoConfig.Description);
 8 
 9             Console.ReadKey();
10         }
11     }

 输出结果:

Name:Hetring.ConfigReader
Version:1.0
Description:This is description.
原文地址:https://www.cnblogs.com/hetring/p/4182579.html