自定义app.config文件的结点

有经验的开发人员都知道在开发.NET应用时可以利用配置文件保存一些常用并且有可能变化的信息,例如日志文件的保存路径、数据库连接信息等等,这样即使生产环境中的参数信息与开发环境不一致也只需要更改配置文件而不用改动源代码再重新编译,极其方便。并且我们一般还约定,在<appSettings>节点保存应用程序的配置信息,在<connectionStrings>中保存数据库连接字符串信息(详见本博客《asp.net夜话之十一:web.config详解》)。
上面的这些方法和约定足以让我们在大部分开发中获得方便,但是在有些情况下有些配置信息可以按组分类存放,如果采用上面的方法不仅不直观,而且读取起来也不是太方便,幸好在.NET里就提供了这样的方法。如果有使用过Log4Net或者Enyim.Caching的朋友,肯定对下面的配置不会陌生:

  1. <sectionGroupname="enyim.com"><sectionname="memcached"type="Enyim.Caching.Configuration.MemcachedClientSection, Enyim.Caching"/></sectionGroup> 

或:

  1. <configSections><sectionname="log4net"type="System.Configuration.IgnoreSectionHandler"/></configSections> 

在出现上面配置的配置文件中,我们就会找到名称为"enyim.com"或者"log4net"的节点,尽管它们本不属于config文件的默认节点,但是通过上面的配置之后程序运行并不会报错。这样一来,相关配置信息也可以很好分类保存起来。
在这里周公演示一个简单的例子,这个例子来源于周公的一个从2006年起就开始开发的自用软件(因为没有美化所以没有免费发布),在这个应用程序的connfig文件中我增加了一些特有的配置,所以新增了一个自己的节点,app.config文件内容如下:

  1. <?xmlversion="1.0"encoding="utf-8"?> 
  2. <configuration> 
  3.   <configSections> 
  4.       <sectionname="SoftwareSettings"type="ImageAssistant.Configuration.SoftwareSettings, ImageAssistant"/> 
  5.   </configSections> 
  6.   <SoftwareSettings> 
  7.     <LoadSettings> 
  8.       <addkey="LoadBmp"value="true"/> 
  9.       <addkey="LoadJpg"value="true"/> 
  10.       <addkey="LoadGif"value="true"/> 
  11.       <addkey="LoadPng"value="false"/> 
  12.     </LoadSettings> 
  13.     <PathSettingsSavePath="C:/ResizeImages/"SearchSubPath="true"/> 
  14.   </SoftwareSettings> 
  15.   <appSettings> 
  16.     <add key="LoadBmp"value="true"/> 
  17.     <addkey="LoadJpg"value="true"/> 
  18.     <add key="LoadGif"value="true"/> 
  19.     <addkey="LoadPng"value="false"/> 
  20.     <add key="IncludeSubPath" value="true"/> 
  21.   </appSettings> 
  22.    
  23. </configuration> 

在config文件中我们使用<section name="SoftwareSettings" type="ImageAssistant.Configuration.SoftwareSettings, ImageAssistant" />告诉应用程序对于配置文件中的SoftwareSettings节点,其对应的类是ImageAssistant程序集中ImageAssistant.Configuration.SoftwareSettings类,并且在<SoftwareSettings>节点中我们还看到有<LoadSettings>节点和<PathSettings>节点,其中<LoadSettings>是一个节点集合,还包含有多个子节点,为了表示清楚这些关系我们需要添加四个类:SoftwareSettings、LoadSettingsCollection、LoadSettingsElement及PathSettingElement。为了发布方便,周公将这四个类的代码放在一个物理文件中,代码如下(注意添加对System.Configuration.dll的引用):

  1. using System; 
  2. using System.Collections.Generic; 
  3. using System.Linq; 
  4. using System.Text; 
  5. using System.Configuration; 
  6.  
  7. //作者:zhoufoxcn(周公) 
  8. //日期:2011-03-08 
  9. //blog:http://blog.csdn.net/zhoufoxcn 或http://zhoufoxcn.blog.51cto.com 
  10. //版权声明:本文允许非商业用途,但必须保证不得去掉本文中的任何链接,违者必究。 
  11. namespace ImageAssistant.Configuration 
  12.     public sealedclass LoadSettingsCollection : ConfigurationElementCollection 
  13.     { 
  14.         private IDictionary<string,bool> settings; 
  15.  
  16.         protected override ConfigurationElement CreateNewElement() 
  17.         { 
  18.             return new LoadSettingsElement(); 
  19.         } 
  20.  
  21.         protected overrideobject GetElementKey(ConfigurationElement element) 
  22.         { 
  23.             LoadSettingsElement ep = (LoadSettingsElement)element; 
  24.  
  25.             return ep.Key; 
  26.         } 
  27.  
  28.         protected override string ElementName 
  29.         { 
  30.             get 
  31.             { 
  32.                 return base.ElementName; 
  33.             } 
  34.         } 
  35.  
  36.         public IDictionary<string,bool> Settings 
  37.         { 
  38.             get 
  39.             { 
  40.                 if (settings ==null
  41.                 { 
  42.                     settings = new Dictionary<string,bool>(); 
  43.                     foreach (LoadSettingsElement ein this
  44.                     { 
  45.                         settings.Add(e.Key, e.Value); 
  46.                     } 
  47.                 } 
  48.                 return settings; 
  49.             } 
  50.         } 
  51.  
  52.         public boolthis[string key] 
  53.         { 
  54.             get 
  55.             { 
  56.                 bool isLoad =true
  57.                 if (settings.TryGetValue(key,out isLoad)) 
  58.                 { 
  59.                     return isLoad; 
  60.                 } 
  61.                 else 
  62.                 { 
  63.                     throw new ArgumentException("没有对'" + key +"'节点进行配置。"); 
  64.                 } 
  65.             } 
  66.         } 
  67.  
  68.     } 
  69.  
  70.     public class LoadSettingsElement : ConfigurationElement 
  71.     { 
  72.         [ConfigurationProperty("key", IsRequired =true)] 
  73.         public string Key 
  74.         { 
  75.             get { return (string)base["key"]; } 
  76.             set { base["key"] = value; } 
  77.         } 
  78.         [ConfigurationProperty("value", IsRequired =true)] 
  79.         public bool Value 
  80.         { 
  81.             get { return (bool)base["value"]; } 
  82.             set { base["value"] = value; } 
  83.         } 
  84.     } 
  85.  
  86.     public class PathSettingElement : ConfigurationElement 
  87.     { 
  88.         /// <summary> 
  89.         ///  
  90.         /// </summary> 
  91.         [ConfigurationProperty("SavePath", IsRequired =true)] 
  92.         public string SavePath 
  93.         { 
  94.             get { return (string)base["SavePath"]; } 
  95.             set { base["SavePath"] = value; } 
  96.         } 
  97.         /// <summary> 
  98.         ///  
  99.         /// </summary> 
  100.         [ConfigurationProperty("SearchSubPath", IsRequired =false, DefaultValue = true)] 
  101.         public bool SearchSubPath 
  102.         { 
  103.             get { return (bool)base["SearchSubPath"]; } 
  104.             set { base["SearchSubPath"] = value; } 
  105.         } 
  106.     } 
  107.  
  108.     /// <summary> 
  109.     /// 对应config文件中的 
  110.     /// </summary> 
  111.     public sealedclass SoftwareSettings : ConfigurationSection 
  112.     { 
  113.         /// <summary> 
  114.         /// 对应SoftwareSettings节点下的LoadSettings子节点 
  115.         /// </summary> 
  116.         [ConfigurationProperty("LoadSettings", IsRequired =true)] 
  117.         public LoadSettingsCollection LoadSettings 
  118.         { 
  119.             get { return (LoadSettingsCollection)base["LoadSettings"]; } 
  120.         } 
  121.  
  122.         /// <summary> 
  123.         /// 对应SoftwareSettings节点下的PathSettings子节点,非必须 
  124.         /// </summary> 
  125.         [ConfigurationProperty("PathSettings", IsRequired =false)] 
  126.         public PathSettingElement PathSetting 
  127.         { 
  128.             get { return (PathSettingElement)base["PathSettings"]; } 
  129.             set { base["PathSettings"] = value; } 
  130.         } 
  131.  
  132.     } 

在上面的代码中可以看到ConfigurationProperty这个属性,这是表示对应的属性在config文件中的属性名,IsRequired表示是否是必须的属性,还有DefaultValue表示属性的默认值。初次之外,我们还要注意以下关系:
SoftwareSettings:根节点,继承自ConfigurationSection。
LoadSettingsCollection:子节点集合,继承自ConfigurationElementCollection。
LoadSettingsElement:子节点,继承自ConfigurationElement。
PathSettingElement:子节点,继承自ConfigurationElement。
编写了如下代码之后,我们又该如何使用上面的类呢?其实很简单,如下:

  1. class Program 
  2.     { 
  3.         static void Main(string[] args) 
  4.         { 
  5.             SoftwareSettings softSettings = ConfigurationManager.GetSection("SoftwareSettings")as SoftwareSettings; 
  6.  
  7.             foreach (string keyin softSettings.LoadSettings.Settings.Keys) 
  8.             { 
  9.                 Console.WriteLine("{0}={1}", key, softSettings.LoadSettings[key]); 
  10.             } 
  11.             Console.WriteLine("SavePath={0},SearchSubPath={1}", softSettings.PathSetting.SavePath, softSettings.PathSetting.SearchSubPath); 
  12.             Console.ReadLine(); 
  13.         } 
  14.     } 

这个程序的运行结果如下:
LoadBmp=True
LoadJpg=True
LoadGif=True
LoadPng=False
SavePath=C:/ResizeImages/,SearchSubPath=True

总结:在上面的config文件中通过<appSettings>也达到了类似的效果,但是通过自定义节点我们可以方便地读取相关的应用程序配置,同时也便于维护。如果在开发过程中遇到本文中类似的情况,不妨采取本文所述的方式。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值