zoukankan      html  css  js  c++  java
  • .net 中读取自定义Config文件

    今天做一个windows插件式服务程序,插件有时要读取配置文件的设置,但是服务是动态加载到服务上的,没有办法作到动态修改服务的配置文件(app.config)。在.net 2.0中有一个ConfigurationManager类可以方面的读取默认的配置文件,如果要自定义读取配置文件,这个类也提供了方法,如下所示:

    var configMap = new ExeConfigurationFileMap { ExeConfigFilename = configFile };
       var config = ConfigurationManager.OpenMappedExeConfiguration(configMap, ConfigurationUserLevel.None);
       var configurationSection = config.GetSection(sectionName);
    
    这种获取到的对象只是这个Section的名称和xml内容,这和ConfigurationManager默认方法GetSection获取到的是一个对象,可以进行强制转换成相应的类型相比,十分的不方便。
    在不想造轮子想法,在google中搜索了很久也没有找到好的解决方法。最后,还是自己研究解决。
    在上面的对象“configurationSection”是一个DefaultSection的类型,它有一个属性SectionInformation,如下所示:
    public System.Configuration.SectionInformation SectionInformation { get; }
    

    这个属性包含了从配置文件中读取到的xml信息,其中这个类型一个关键方法:

    public string GetRawXml()

    用于获取配置中的xml内容,举例如下:

    有如下配置文件:
       1: <configuration>
       2:   <configSections>
       3:     <sectionGroup name="WeiboClientSectionGroup">
       4:       <section name="SinaSection" type="System.Configuration.NameValueSectionHandler,System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
       5:       <section name="QQSection" type="System.Configuration.NameValueSectionHandler,System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
       6:       <section name="SohuSection" type="System.Configuration.NameValueSectionHandler,System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
       7:       <section name="NetEaseSection" type="System.Configuration.NameValueSectionHandler,System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
       8:     </sectionGroup>
       9:     <sectionGroup name="WeiboSectionGroup">
      10:       <section name="SinaSection" type="System.Configuration.NameValueSectionHandler,System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
      11:       <section name="QQSection" type="System.Configuration.NameValueSectionHandler,System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
      12:       <section name="SohuSection" type="System.Configuration.NameValueSectionHandler,System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
      13:       <section name="NetEaseSection" type="System.Configuration.NameValueSectionHandler,System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
      14:     </sectionGroup>
      15:   </configSections>
      16:   <WeiboClientSectionGroup>
      17:     <SinaSection>
      18:       <add key="AccessToken" value=""/>
      19:       <add key="AccessTokenSecret" value=""/>
      20:       <add key="ResultFormat" value="Json"/>
      21:     </SinaSection>
      22:     <!--<QQSection>
      23:       <add key="AccessToken" value=""/>
      24:       <add key="AccessTokenSecret" value=""/>
      25:       <add key="ResultFormat" value="Json"/>
      26:     </QQSection>-->
      27:     <QQSection>
      28:       <add key="AccessToken" value=""/>
      29:       <add key="AccessTokenSecret" value=""/>
      30:       <add key="ResultFormat" value="Json"/>
      31:     </QQSection>
      32:  
      33:     <SohuSection>
      34:       <add key="AccessToken" value=""/>
      35:       <add key="AccessTokenSecret" value=""/>
      36:       <add key="ResultFormat" value="Json"/>
      37:     </SohuSection>
      38:     <NetEaseSection>
      39:       <add key="AccessToken" value=""/>
      40:       <add key="AccessTokenSecret" value=""/>
      41:       <add key="ResultFormat" value="Json"/>
      42:     </NetEaseSection>
      43:   </WeiboClientSectionGroup>
      44:   <WeiboSectionGroup>
      45:     <SinaSection>
      46:       <add key="AppKey" value=""/>
      47:       <add key="AppSecret" value=""/>
      48:       <add key="AuthorizeUri" value="http://api.t.sina.com.cn/oauth/authorize"/>
      49:       <add key="RequestTokenUri" value="http://api.t.sina.com.cn/oauth/request_token"/>
      50:       <add key="AccessTokenUri" value="http://api.t.sina.com.cn/oauth/access_token"/>
      51:       <add key="CallBackUri" value="null"></add>
      52:     </SinaSection>
      53:     <QQSection>
      54:       <add key="AppKey" value=""/>
      55:       <add key="AppSecret" value=""/>
      56:       <add key="AuthorizeUri" value="https://open.t.qq.com/cgi-bin/authorize"/>
      57:       <add key="RequestTokenUri" value="https://open.t.qq.com/cgi-bin/request_token"/>
      58:       <add key="AccessTokenUri" value="https://open.t.qq.com/cgi-bin/access_token"/>
      59:       <add key="CallBackUri" value="null"></add>
      60:     </QQSection>
      61:     <SohuSection>
      62:       <add key="AppKey" value=""/>
      63:       <add key="AppSecret" value=""/>
      64:       <add key="AuthorizeUri" value="http://api.t.sohu.com/oauth/authorize"/>
      65:       <add key="RequestTokenUri" value="http://api.t.sohu.com/oauth/request_token"/>
      66:       <add key="AccessTokenUri" value="http://api.t.sohu.com/oauth/access_token"/>
      67:       <add key="CallBackUri" value="null"></add>
      68:     </SohuSection>
      69:     <NetEaseSection>
      70:       <add key="AppKey" value=""/>
      71:       <add key="AppSecret" value=""/>
      72:       <add key="AuthorizeUri" value="http://api.t.163.com/oauth/authenticate"/>
      73:       <add key="RequestTokenUri" value="http://api.t.163.com/oauth/request_token"/>
      74:       <add key="AccessTokenUri" value="http://api.t.163.com/oauth/access_token"/>
      75:       <add key="CallBackUri" value="null"></add>
      76:     </NetEaseSection>
      77:   </WeiboSectionGroup>
      78: <startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>

    我们sectionName=”WeiboSectionGroup/SinaSection”

    上面的函数就返回如下字符串:

    <SinaSection>
          <add key="AppKey" value=""/>
          <add key="AppSecret" value=""/>
          <add key="AuthorizeUri" value="http://api.t.sina.com.cn/oauth/authorize"/>
          <add key="RequestTokenUri" value="http://api.t.sina.com.cn/oauth/request_token"/>
          <add key="AccessTokenUri" value="http://api.t.sina.com.cn/oauth/access_token"/>
          <add key="CallBackUri" value="null"></add>
        </SinaSection>
    

    另外此类型,还有一个Type属性,是字符串类型,如上面的配置,读取出来就是“

    System.Configuration.NameValueSectionHandler,System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
    

    根据上面的信息,我们就可以首先使用反射的方式,生成对象NameValueSectionHandler,现调用此对的Create方法进行创建NameValueCollection,如下所示:

    private static TReturn LoadSection<TReturn>(SectionInformation information) where TReturn:class 
            {
                string[] strs = information.Type.Split(",".ToCharArray(), 2);
                var handler = (IConfigurationSectionHandler)Assembly.Load(strs[1]).CreateInstance(strs[0]);
                var doc = new XmlDocument();
                doc.LoadXml(information.GetRawXml());
                if (handler != null)
                    return (TReturn)handler.Create(null, null, doc.ChildNodes[0]);
                return null;
            }
    

    下面提供一个完整的实例:

       1: public abstract class ConfigBase<T> where T:class 
       2:     {
       3:         protected ConfigBase(string sectionName, string configFile)
       4:         {
       5:             if (string.IsNullOrEmpty(configFile))
       6:             {
       7:                 Section = (T)ConfigurationManager.GetSection(sectionName);
       8:             }
       9:             else
      10:             {
      11:                 var configMap = new ExeConfigurationFileMap { ExeConfigFilename = configFile };
      12:                 var config = ConfigurationManager.OpenMappedExeConfiguration(configMap, ConfigurationUserLevel.None);
      13:                 var configurationSection = config.GetSection(sectionName);
      14:                 if (configurationSection != null)
      15:                 {
      16:                     Section = LoadSection(configurationSection.SectionInformation);
      17:                 }
      18:             }
      19:         }
      20:  
      21:         private static TReturn LoadSection<TReturn>(SectionInformation information) where TReturn:class 
      22:         {
      23:             string[] strs = information.Type.Split(",".ToCharArray(), 2);
      24:             var handler = (IConfigurationSectionHandler)Assembly.Load(strs[1]).CreateInstance(strs[0]);
      25:             var doc = new XmlDocument();
      26:             doc.LoadXml(information.GetRawXml());
      27:             if (handler != null)
      28:                 return (TReturn)handler.Create(null, null, doc.ChildNodes[0]);
      29:             return null;
      30:         }
      31:  
      32:         protected T LoadSection(SectionInformation information)
      33:         {
      34:             return LoadSection<T>(information);
      35:         }
      36:  
      37:         protected T Section { get; private set; }
      38:     }

     

    上面是一个抽象类,从上面的类进行继承,就可以实现功能,如下所示:

       1: public class ClientConfig : ConfigBase<NameValueCollection>
       2:     {
       3:         public ClientConfig(WeiboType weiboType)
       4:             : this(weiboType, null)
       5:         {
       6:         }
       7:  
       8:         public ClientConfig(WeiboType weiboType, string configFile)
       9:             : base(string.Format("WeiboClientSectionGroup/{0}Section", weiboType), configFile)
      10:         {
      11:         }
      12:  
      13:         public string AccessToken
      14:         {
      15:             get { return Section["AccessToken"]; }
      16:         }
      17:  
      18:         public string AccessTokenSecret
      19:         {
      20:             get { return Section["AccessTokenSecret"]; }
      21:         }
      22:  
      23:         public ResultFormat ResultFormat
      24:         {
      25:             get { return (ResultFormat)Enum.Parse(typeof(ResultFormat), Section["ResultFormat"]); }
      26:         }
      27:     }

     

     

     
     
  • 相关阅读:
    2020年4月4日训练
    HZNU Training 17 for Zhejiang Provincial Competition 2020
    [kuangbin带你飞]专题四 最短路练习
    三分法
    洛谷多校第一周续
    洛谷春季 ACM 多校训练第五周
    简单数学三月小结
    线段树&树状数组
    图论三月小结
    Java中Double保留后小数位的几种方法
  • 原文地址:https://www.cnblogs.com/LifelongLearning/p/2179265.html
Copyright © 2011-2022 走看看