App.config的学习笔记

昨天基本弄清config的使用之后,再看WP的API,晕了。结果WP不支持system.configuration命名空间,这意味着想在WP上用App.config不大可能了。

WP具体支持API请查看

.net WP API

API reference

不过还是记录下App.config的使用。

有很大部分是从MSDN学来的,如果有人看我的这篇文章的话可以先去看看MSDN的相关章节 http://msdn.microsoft.com/en-us/library/system.configuration.configuration(v=vs.110).aspx

一.appSettings

这个比较简单,也有很多资料讲到,在我的C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config中,有machine.config这个文件

有下面节选

1 <configuration>
2     <configSections>
3         <section name="appSettings" type="System.Configuration.AppSettingsSection, System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" restartOnExternalChanges="false" requirePermission="false"/>
4         <section name="connectionStrings" type="System.Configuration.ConnectionStringsSection, System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" requirePermission="false"/>

后面长串省略………………

所以appSettings是一个section,当在配置文件中输入  <appSettings>节点时,系统会帮我们映射到System.Configuration.AppSettingsSection这个类中去,用reflector看看这个类

继承自ConfigurationSection

1   private static volatile ConfigurationProperty s_propAppSettings;
2   private static volatile ConfigurationProperty s_propFile;

其跟App.config中映射的字段

1  ConfigurationProperty property = new ConfigurationProperty(null, typeof(KeyValueConfigurationCollection), null, ConfigurationPropertyOptions.IsDefaultCollection);
2  ConfigurationProperty property2 = new ConfigurationProperty("file", typeof(string), string.Empty, ConfigurationPropertyOptions.None);

1 s_propAppSettings = property;

2 s_propFile = property2;

属性暴露出来为:

file(attribute)

不作为元素:

 1   [ConfigurationProperty("file", DefaultValue="")]
 2         public string File
 3         {
 4             get
 5             {
 6                 string str = (string) base[s_propFile];
 7                 if (str == null)
 8                 {
 9                     return string.Empty;
10                 }
11                 return str;
12             }
13             set
14             {
15                 base[s_propFile] = value;
16             }
17         }

element:

1  [ConfigurationProperty("", IsDefaultCollection=true)]
2         public KeyValueConfigurationCollection Settings
3         {
4             get
5             {
6                 return (KeyValueConfigurationCollection) base[s_propAppSettings];
7             }
8         }

对于不是嵌套的element,而是直接作为section的子节点集合,就照这样写,这样写没有在App.config的对应名字,看起来全是add元素(当然也可以有,后面会说明)

再来看看KeyValueConfigurationCollection这个集合继承自ConfigurationElementCollection

其中重要的两个方法:

1    protected override ConfigurationElement CreateNewElement()
2         {
3             return new KeyValueConfigurationElement();
4         }
5
6         protected override object GetElementKey(ConfigurationElement element)
7         {
8             return ((KeyValueConfigurationElement) element).Key;
9         }

所以其实在每个Add中,Add的是KeyValueConfigurationElement,这个类的Key属性作为集合的关键字,再来看看KeyValueConfigurationElement类,这个类继承自ConfigurationElement

关键部分:

 1   private static readonly ConfigurationProperty _propKey = new ConfigurationProperty("key", typeof(string), string.Empty, ConfigurationPropertyOptions.IsKey | Configurat     ionPropertyOptions.IsRequired);
 2   private static readonly ConfigurationProperty _propValue = new ConfigurationProperty("value", typeof(string), string.Empty, ConfigurationPropertyOptions.None);

 3      [ConfigurationProperty("key", Options=ConfigurationPropertyOptions.IsKey, DefaultValue="")]
 4         public string Key
 5         {
 6             get
 7             {
 8                 return (string) base[_propKey];
 9             }
10         }
11      [ConfigurationProperty("value", DefaultValue="")]
12         public string Value
13         {
14             get
15             {
16                 return (string) base[_propValue];
17             }
18             set
19             {
20                 base[_propValue] = value;
21             }
22         }

具体到element的key,value了。这样我们也可以自定义节点了。

二.模仿appSettings做自己的setting

创建一个控制台应用和一个类库,在控制台中先添加system.configuration程序集的引用。然后我们写上自己想要的App.config的内容。如下

 1 <?xml version="1.0" encoding="utf-8" ?>
 2 <configuration>
 3
 8   <Songs ChannelId="1">
 9     <add  name="1.mp3" length="100" />
10     <add  name="2.mp3" length="100" />
11     <add  name="3.mp3"/>
12     <add length="200"/>
13   </Songs>
14
15 </configuration>

这样算是定义好了一些配置,其中有些song配置使用了默认的值。

但是为了使Songs这个Section工作起来,我们也需要像Appsettings一样添加自定义Section,我们添加 <configSections>元素,再在里面添加Section,添加好,完整如下

 1 <?xml version="1.0" encoding="utf-8" ?>
 2 <configuration>
 3   <configSections>
 7     <section name="Songs" type="ConfigLib.SongsSection,ConfigLib"/>
 8   </configSections>
 9
10   <Songs ChannelId="1">
11     <add  name="1.mp3" length="100" />
12     <add  name="2.mp3" length="100" />
13     <add  name="3.mp3"/>
14     <addlength="200"/>
15   </Songs>
16
17 </configuration>

其中ConfigLib为我们一开始添加的库的名字 ConfigLib.SongsSection为要映射到的类。

接下看看SongsSection类。

同样在ConfigLib这个Lib中添加system.configuration这个dll,然后使SongsSection这个类去继承ConfigurationSection类

1 namespace ConfigLib
2 {
3     public class SongsSection:ConfigurationSection
4     {
5     }
6 }

由于我们的appSettings的子节点都是数据的单个点,总共是一个集合,所以我们还要一个集合类用来存放所有的song.这个集合要继承ConfigurationElementCollection类

1 namespace ConfigLib
2 {
3     class Songcollection:ConfigurationElementCollection
4     {
5     }
6 }

但是这样是编译不过的,因为ConfigurationElementCollection类里有2个标注为abstract的方法需要我们子类来实现,先让它编译通过,如下

 1  public class Songcollection:ConfigurationElementCollection
 2     {
 3         protected override ConfigurationElement CreateNewElement()
 4         {
 5             throw new NotImplementedException();
 6         }
 7         protected override object GetElementKey(ConfigurationElement element)
 8         {
 9             throw new NotImplementedException();
10         }
11     }

先不管实现,我们用这个Collection来装song.回到SongsSection类,我们可以使用上面的集合了,像appSettings那样,但要注意,我们为Songs这个Section添加了类似XML中属性(attribute)的channleid,由于这个不是Element,是个int类型(后面还有ConfigurationElement类),所以我们在类中属性(Property)中使用的时候这个的时候不会跑到element中去,它会乖乖在XML的属性位置。代码如下

 1 namespace ConfigLib
 2 {
 3     public class SongsSection:ConfigurationSection
 4     {
 5         private readonly ConfigurationProperty collectionproperty = new ConfigurationProperty(null, typeof(Songcollection), null, ConfigurationPropertyOptions.IsDefaultCollection);
 6         [ConfigurationProperty("",IsDefaultCollection=true)]
 7         public  Songcollection SongCollection
 8         {
 9             get
10             {
11                 return (Songcollection)this[collectionproperty];
12
13             }
14         }
15         [ConfigurationProperty("ChannelId", IsKey = false, DefaultValue = "-1")]
16         public int ChannelId
17         {
18             get
19             {
20                 return (int)this["ChannelId"];
21             }
22         }
23     }
24 }

其中SongCollection属性的写法很像appSettings的写法。

接下来看看Songcollection这个集合类最简单的写法:

 1 namespace ConfigLib
 2 {
 3    public  class Songcollection:ConfigurationElementCollection
 4     {
 5         protected override ConfigurationElement CreateNewElement()
 6         {
 7             return new SongElement();
 8         }
 9         protected override object GetElementKey(ConfigurationElement element)
10         {
11             return ((SongElement)element).Name;
12         }
13
14     }
15 }

集合类的很多属性我们使用父类的,字面意思都比较好理解,其中GetElementKey是为这个集合指定关键字的,有点像数据库中的Key,这个Key不能重复,并且我们可以通过

这个Key获得集合中的元素(SongElement).

集合中主要是Element,Element基本就和XML中Element一样,SongElement这个类如下,用这个类(SongElement)定义的变量就是(app.config)XML中的Element,而不是Attribute,(类中的所有简单类型都在Attribute中出现)

 1 namespace ConfigLib
 2 {
 3   public  class SongElement:ConfigurationElement
 4     {
 5         [ConfigurationProperty("name",IsKey=true,DefaultValue="default.mp3")]
 6         public string Name
 7         {
 8             get
 9             {
10                 return (string)this["name"];
11             }
12         }
13         [ConfigurationProperty("length", IsKey = false, DefaultValue = "-1")]
14         public int  Length
15         {
16             get
17             {
18                 return (int)this["length"];
19             }
20         }
21     }
22 }

为每个XML的attribute设置默认值,并且不为必须的,写App.config的时候保证Key(这里是歌的名字)不重复,如果需要通过索引访问song的集合,在集合中加如下索引器:

1     public SongElement this[int index]
2         {
3             get
4             {
5                 return (SongElement)BaseGet(index);
6             }
7         }

由于集合是默认的AddClear类型,所以我们的XML元素(element)虽然存在,但是要写成add,clear形式,(如果有clear,clear写在哪,那么之前add过的元素就都不见了)

代码下载

App.config还可以改成下面这样

 1 <?xml version="1.0" encoding="utf-8" ?>
 2 <configuration>
 3   <configSections>
 4     <section name="Songs" type="ConfigLib.SongsSection,ConfigLib"/>
 5   </configSections>
 6   <Songs ChannelId="1">
 7     <song  name="1.mp3" length="100" />
 8     <song  name="2.mp3" length="100" />
 9     <song  name="3.mp3"/>
10     <song length="200"/>
11   </Songs>
12 </configuration>

把add改成了song,这样顺眼一点

那仅仅只要在集合类中添加:

 1   protected override string ElementName
 2          {
 3              get
 4              {
 5                  return "song";
 6              }
 7          }
 8    public override ConfigurationElementCollectionType CollectionType
 9          {
10              get
11              {
12                  return ConfigurationElementCollectionType.BasicMap;
13              }
14          }

就可以了

如果App.config改为下面这样:

 1 <?xml version="1.0" encoding="utf-8" ?>
 2 <configuration>
 3   <configSections>
 4     <section name="Songs" type="ConfigLib.SongsSection,ConfigLib"/>
 5   </configSections>
 6   <Songs ChannelId="1">
 7     <special_special_song specialsongname="special_1.mp3"/>
 8     <specialsongs>
 9       <specialsong specialsongname="special_2.mp3"/>
10       <specialsong specialsongname="special_3.mp3"/>
11       <specialsong specialsongname="special_4.mp3"/>
12     </specialsongs>
13     <song  name="1.mp3" length="100" />
14     <song  name="2.mp3" length="100" />
15     <song  name="3.mp3"/>
16     <song length="200"/>
17   </Songs>
18 </configuration>

一样的道理,加一个SpecialSongElement类和容纳这个类的集合SpecialSongCollection,然后再在Section中做添加即可,在section类中,第一个

<special_special_song specialsongname="special_1.mp3"/>对应:
1     [ConfigurationProperty("special_special_song", IsKey = false)]
2         public SpecialSongElement SpecialSong
3         {
4             get
5             {
6                 return (SpecialSongElement)this["special_special_song"];
7             }
8         }

而集合

 <specialsongs>对应:
1   [ConfigurationProperty("specialsongs", IsKey = false, IsDefaultCollection = false)]
2         public SpecialSongCollection SpecialSongs
3         {
4             get
5             {
6                 return (SpecialSongCollection)this["specialsongs"];
7             }
8         }

注意IsDefaultCollection = false。这个SpecialSongCollection集合跟前面的集合基本一样。

最后的效果:

代码下载

如果有多个Section的时候可以考虑使用sectionGroup来给各个Section分组

像系统的C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config\machine.config一样

还有虽然微软不提倡使用IConfigurationSectionHandler来解析Section,但是我觉得这个方法知道也不错,这个解析方法是把getsection中的section作为根XmlNode,传到接口实现的方法  public object Create(object parent, object configContext, System.Xml.XmlNode section)中

其中System.Xml.XmlNode section参数就是根xmlNode,然后就可以操作Xml了。

时间: 2024-10-07 07:36:38

App.config的学习笔记的相关文章

asp.net web.config的学习笔记

原文地址:http://www.cnblogs.com/Bulid-For-NET/archive/2013/01/11/2856632.html 一直都对web.config不太清楚.这几天趁着项目不紧赶紧再恶补下,发现确实是有很多原来不明白的地方.特意记录下来,希望能与各位看官共同进步. 小弟自学笔记,有不对的地方还请大神指出来. 学习之前,我是抱着一个完全不知道的态度开始的.我想这个方法适用于很多地方,不是有个故事吗:杯子里的水倒掉才能装进去更多的水.所以有很多地方记录的都是挺基础的知识,

iOS APP开发概述----学习笔记001

之前开发过一些Android APP,现在开始学习iOS开发,未来实际工作应该会用到,未雨绸缪. 一.了解其系统层次架构 其系统分层四层,其详细如下: 二.开发平台组建 三.动手实践 可以自己动手,结合swift和MVC框架,写一个计算机的小例子. 版权声明:本文为博主原创文章,未经博主允许不得转载.

Qt学习笔记-Widget布局管理

Qt学习笔记4-Widget布局管理 以<C++ GUI Programming with Qt 4, Second Edition>为参考 实例:查找对话框 包含三个文件,finddialog.h,finddialog.cpp及main.cpp. //finddialog.h代码 #ifndef FINDDIALOG_H#define FINDDIALOG_H #include <QDialog> class QCheckBox;class QLabel;class QLineE

Sencha学习笔记4: Creating your First App - 官方创建您的第一个Sencha Touch应用指导

英文原文地址:http://docs.sencha.com/touch/2.3.1/#!/guide/first_app (天地会珠海分舵声明:本翻译文章建议读者参照英文原文进行阅读,因为原文包含了实时代码编辑和预览的功能,这在csdn是不能做到的,所以下面只是提供了相应的截图,而非真实的演示) Required Software 软件需求 请参考<Sencha学习笔记1: Getting Started with Sencha Touch - 官方Sencha Touch入门指南> Crea

软件测试第六周学习笔记之“Win8 APP应用程序的白盒测试”

这周的学习笔记我想写点自己关于实验中碰到的问题和感想. 因为这次做的是白盒测试,所以我决定去测试一下上回测试的app的功能函数. 这次我用的是单元测试项目来做的白盒测试: 创建单元测试的步骤: 1.点击 “文件”->“添加”->“新建项目” 2.选择 windows应用程序-> 单元测试项目 3.在解决方案资源管理器中为单元测试项目下的引用上右击选择添加引用 4.选择解决方案下的项目中的用来测试的win8应用 接下来是单元测试的代码部分的编写了: 我要测试的是该项目中的一个字符串转化编码

Android学习笔记----Error:Execution failed for task &#39;:app:validateDebugSigning&#39;. &gt; Keystore file F:\myAndroid3\android_s

导入下载的工程出现这个错误,追究其原因是是下载的工程中有指定使用的Keystore文件的路径, 所以我们可以通过Android studio File->ProjectStructure->选择app ,再选择signing 把Store File里指定的Keystore文件的路径删除,或者填写自己的Keystore文件的路径 然后点击ok,再clean下工程即可 Android学习笔记----Error:Execution failed for task ':app:validateDebu

APPCAN学习笔记---app快速开发AppCan.cn平台概述

1.APPCAN学习笔记---app快速开发AppCan.cn平台概述 1. 平台概述 技术qq交流群:JavaDream:251572072 AppCan.cn开发平台是基于HTML5技术的跨平台移动应用快速开发一体化解决方案. 开发者利用HTML5+CSS3+JavaScript技术可以快速地开发与本地应用体验相媲美的移动应用. AppCan.cn平台提供了UI快速开发框架.本地功能调用API接口.应用打包系统.IDE集成开发环境和本地应用调试模拟器, 预置数百套界面模板和数十种应用插件,提

学习笔记:APP切图那点事儿–详细介绍android和ios平台

学习笔记:APP切图那点事儿–详细介绍android和ios平台 转载自:http://www.woofeng.cn/articles/168.html   版权归原作者所有 作者:亚茹有李 原文地址:http://blog.boocss.com/app-android-ios/ 一.android版 在做android版本设计的时候,尺寸有很多种,这时我们要以一种尺寸为基准,那这个基准尺寸是480px*800px,设计图完成之后就开始切图了 需要注意的: A:android主要有3种屏,即:

.net学习笔记----WebConfig.config常用配置节点介绍

一.配置文件入门 .Net提供了一种保存项目配置信息的办法,就是利用配置文件,配置文件的后缀一般是.config.在WinForm程序中配置文件一般是App.config.在Asp.net中一般默认是web.config. 一个.config配置文件都是基于XML的文本文件,并且可以保存到Web应用程序中的任何目录中.在发布Web应用程序时web.config文件并不编译进dll文件中.将来如果客户端发生了变化,仅仅需要使用记事本打开Web.config文本编辑相关的设置就可以重新正常使用,而无