昨天基本弄清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);

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

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

二.模仿appSettings做自己的setting

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

  1. <?xml version="1.0" encoding="utf-8" ?>
  2. <configuration>
  3.  
  4. <Songs ChannelId="1">
  5. <add name="1.mp3" length="100" />
  6. <add name="2.mp3" length="100" />
  7. <add name="3.mp3"/>
  8. <add length="200"/>
  9. </Songs>
  10.  
  11. </configuration>

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

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

  1. <?xml version="1.0" encoding="utf-8" ?>
  2. <configuration>
  3. <configSections>
  4. <section name="Songs" type="ConfigLib.SongsSection,ConfigLib"/>
  5. </configSections>
  6.  
  7. <Songs ChannelId="1">
  8. <add name="1.mp3" length="100" />
  9. <add name="2.mp3" length="100" />
  10. <add name="3.mp3"/>
  11. <addlength="200"/>
  12. </Songs>
  13.  
  14. </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类中,第一个

  1. <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. }

而集合

  1. <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了。

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

  1. asp.net web.config的学习笔记

    原文地址:http://www.cnblogs.com/Bulid-For-NET/archive/2013/01/11/2856632.html 一直都对web.config不太清楚.这几天趁着项目 ...

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

    之前开发过一些Android APP,如今開始学习iOS开发,未来实际工作应该会用到.未雨绸缪. 一.了解其系统层次架构 其系统分层四层,其具体例如以下: 第一层:Core OS watermark/ ...

  3. App.config

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

  4. Beego学习笔记——Config

    配置文件解析 这是一个用来解析文件的库,它的设计思路来自于database/sql,目前支持解析的文件格式有ini.json.xml.yaml,可以通过如下方式进行安装: go get github. ...

  5. Ruby学习笔记4: 动态web app的建立

    Ruby学习笔记4: 动态web app的建立 We will first build the Categories page. This page contains topics like Art, ...

  6. go微服务框架kratos学习笔记五(kratos 配置中心 paladin config sdk [断剑重铸之日,骑士归来之时])

    目录 go微服务框架kratos学习笔记五(kratos 配置中心 paladin config sdk [断剑重铸之日,骑士归来之时]) 静态配置 flag注入 在线热加载配置 远程配置中心 go微 ...

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

    这周的学习笔记我想写点自己关于实验中碰到的问题和感想. 因为这次做的是白盒测试,所以我决定去测试一下上回测试的app的功能函数. 这次我用的是单元测试项目来做的白盒测试: 创建单元测试的步骤: 1.点 ...

  8. 高性能Cordova App开发学习笔记

    高性能Cordova App开发学习笔记 文件结构 添加插件 构建准备 各个www的作用,prepare命令会将hello\www的内容会拷贝到platform下的wwww目录,知道该改哪里了吧?如果 ...

  9. PHP 开发 APP 接口 学习笔记与总结 - Redis 缓存

    Redis 可以定期将数据备份到磁盘中(持久化),同时不仅仅支持简单的key/value 类型的数据,同时还提供list,set,hash等数据结构的存储:Memcache 只是简单的key/valu ...

随机推荐

  1. Android wifi状态三种广播

    public class NetworkConnectChangedReceiver extends BroadcastReceiver{      @Override      public voi ...

  2. 土法炼钢:怎么实现一个简单的B+Tree In-Disk

    1. 写在前面 说起B+树,大家应该都很熟悉.B+树是一种平衡的多路搜索树,广泛在操作系统和数据库系统用作索引.相比于内存的存取速度,磁盘I/O存取的开销要高上几个数量级.而将B+树用作索引时,它可以 ...

  3. 模糊查询(LIKE)and (PATINDEX() . CHARINDEX())

    SQL中的模糊查询一般来说使用模糊查询,大家都会想到LIKE  select * from table where a like '%字符%' 如果一个SQL语句中用多个 like模糊查询,并且记录条 ...

  4. 慕课网-安卓工程师初养成-4-7 Java循环语句之 while

    来源: http://www.imooc.com/code/1420 生活中,有些时候为了完成任务,需要重复的进行某些动作.如参加 10000 米长跑,需要绕 400 米的赛道反复的跑 25 圈.在 ...

  5. JS 点击按钮后弹出遮罩层,有关闭按钮

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <t ...

  6. javascript设计模式-桥接模式

    在系统中,某些类由于自身逻辑,具有两个或两个以上维度的变化,如何使得该类型可以沿多个方向变化,但又不引入额外的复杂度,这就是桥接模式要解决的问题. 定义:桥接模式(Bridge),将抽象部分与它的实现 ...

  7. 解决jQuery插件重名问题

    jQuery第三方插件命名冲突: 1.以某种方法为自己创建的jQuery插件添加命名空间,以免名称冲突.比如:在自己的插件名之前添加某类名称前缀. 2.避免影响全局命名空间.将自己的所有函数调用和变量 ...

  8. Ax Grid 的显示根据用户的需求动态排序。

    点击方向按钮上下移动记录. 设计思路. 以临时表TmpTable1举例. 在表中加一个real类型字段(eg:ColumnSeq)用于排序,给表建一个ColumnSeq字段的索引ColumnSeqId ...

  9. py2.7+pyqt4开发端口检测工具

    使用工具:python2.7,pyqt4,pyinstaller,pywin32 先贴代码 import sys from PyQt4 import QtGui,QtCore import threa ...

  10. javascript之值传递与引用传递

    在分析这个问题之前,我们需了解什么是按值传递(call by value),什么是按引用传递(call by reference).在计算机科学里,这个部分叫求值策略(Evaluation Strat ...