今天做一个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:     }
 
 
 
 
 

.net 中读取自定义Config文件的更多相关文章

  1. 【Core】.NET Core中读取App.config配置文件

    1.项目中添加App.config文件 因为.NET Core的项目本质是控制台应用,所以ConfigurationManager的API会去默认读取app.config配置文件,而不是web.con ...

  2. C#Unit单元测试之读取Web.config文件

    长期一来,我们所完成的项目都没有写单元测试,今天我一时兴起,决定给自己写的代码写单元测试,简单的测试代码分分钟完成了,一运行测试,就懵逼了.没能达到我的预期效果,而是出现图1所示错误. 图1:单元测试 ...

  3. matlab中读取txt数据文件(txt文本文档)

    matlab中读取txt数据文件(txt文本文档) 根据txt文档不同种类介绍不同的读取数据方法 一.纯数据文件(没有字母和中文,纯数字) 对于这种txt文档,从matalb中读取就简单多了 例如te ...

  4. C# 操作自定义config文件

    示例文件:DB.config 1.读取 //先实例化一个ExeConfigurationFileMap对象,把物理地址赋值到它的 ExeConfigFilename 属性中: ExeConfigura ...

  5. matlab中读取txt数据文件(转)

    根据txt文档不同种类介绍不同的读取数据方法 一.纯数据文件(没有字母和中文,纯数字) 对于这种txt文档,从matalb中读取就简单多了 例如test.txt文件,内容为“17.901 -1.111 ...

  6. 读取Excel二进制写入DB,并从DB中读取生成Excel文件

    namespace SendMailSMSService { class Program { static void Main(string[] args) { var connString = Sq ...

  7. PCB 电测试--测试点数自动输出到流程指示中(读取TGZ Stephdr文件)

    好不容易实现了 <PCB 无需解压,直接读取Genesis TGZ指定文件 > 正好这里有一项需求:PCB电测试--测试点数自动输出到流程指示中 一.自动输出测试点小结; 1.由于历史原因 ...

  8. Spark- Spark从SFTP中读取zip压缩文件数据做计算

    我们遇到个特别的需求,一个数据接入的流程跑的太慢,需要升级为用大数据方式去处理,提高效率. 数据: 数据csv文件用Zip 压缩后放置在SFTP中 数据来源: SFTP 数据操作: 文件和它的压缩包一 ...

  9. C#窗体中读取修改xml文件

    由于之前没有操作过xml文件,尤其是在窗体中操作xml,脑子一直转不动,而且很抵制去做这个功能,终于还是突破了自己通过查询资料完成了这个功能,在此记录一下自己的成果. 功能说明:程序中存在的xml文件 ...

随机推荐

  1. VS2010在运行状态下编辑代码

    在VS2010环境下,当程序处于调试运行状态时,编辑代码会出现下图提示框: 这就给边编辑代码边查看程序运行效果带来不便. 解决方法:在程序没有运行的时候,打开菜单“工具”——>“选项”——> ...

  2. Updating Protobuf and GRPC in Golang

    转自: http://russmatney.com/techsposure/update-protobuf-golang-grpc/ TL;DR: When protobuf updates, all ...

  3. Nagios 安装配置

    ##Debian 6 安装server # apt-get install nagios* 一路设置好各种密码,成功后访问 http://ip/nagios3 既可,默认用户*nagiosadmin* ...

  4. 高吞吐量的分布式发布订阅消息系统Kafka-- 管理工具 Kafka Manager

    一.概述 Kafka在雅虎内部被很多团队使用,媒体团队用它做实时分析流水线,可以处理高达20Gbps(压缩数据)的峰值带宽. 为了简化开发者和服务工程师维护Kafka集群的工作,构建了一个叫做Kafk ...

  5. 使用aspose.cell导出excel需要注意什么?

    1.如果导出的数据源是汇总出来的,最好方法是将数据源放到缓存里面,当基本数据源变化的时候,在改变数据2.使用模板导出EXCEL,这样很多样式可以在模板文件里面直接设置,例如:默认打开页签,让列头固定3 ...

  6. Linux中vi显示中文乱码的问题

    由于在windows下默认是gb编码,而我的vim默认是utf-8(gedit默认也是utf-8),所以打开会成乱码.修改了一下配置文件,使vi支持gb编码就好了.$vi ~/.vimrclet &a ...

  7. archlinux 下 nignx + php 出现 no input file specified

    奇葩的问题,配置 nginx + php + mysql 后,加一个站点: server { listen 80; server_name wei.abc.com; root /www/wei.abc ...

  8. JavaScript中的String对象

        String对象提供的方法用于处理字符串及字符. 常用的一些方法: charAt(index):返回字符串中index处的字符. indexOf(searchValue,[fromIndex] ...

  9. Privacy Policy

    MINE Privacy Policy This unit values your privacy. You are using our service, we may collect and use ...

  10. 一种高效的 vector 四则运算处理方法

    实现 vector 的四则运算 这里假设 vector 的运算定义为对操作数 vector 中相同位置的元素进行运算,最后得到一个新的 vector.具体来说就是,假如 vector<int&g ...