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

 

我们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(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 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(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(information);
  35:         }
  36:  
  37:         protected T Section { get; private set; }
  38:     }

 

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

   1: public class ClientConfig : ConfigBase
   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:     }

 

 

 

 

 
 

你可能感兴趣的:(.net 中读取自定义Config文件)