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


    一、引子

    你是否也遇到过这样的问题:项目很多配置都写到了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.
  • 相关阅读:
    Codeforces Round #536 E. Lunar New Year and Red Envelopes /// 贪心 记忆化搜索 multiset取最大项
    牛客网暑期ACM多校训练营(第五场) F
    关于线段树or 树状树状 在二维平面搞事情!Orz
    ZOJ 3822 ( 2014牡丹江区域赛D题) (概率dp)
    HDU4336 Card Collector (概率dp+状压dp)
    POJ 2151 Check the difficulty of problems(概率DP)
    CF E2
    HDU4089 Activation(概率DP+处理环迭代式子)
    HDU4035 Maze (概率DP)
    牛客 Rabbit的数列 (线段树维护值为x的个数+区间覆盖)
  • 原文地址:https://www.cnblogs.com/hetring/p/4182579.html
Copyright © 2020-2023  润新知