App.config的学习笔记
昨天基本弄清config的使用之后,再看WP的API,晕了。结果WP不支持system.configuration命名空间,这意味着想在WP上用App.config不大可能了。
WP具体支持API请查看
不过还是记录下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这个文件
有下面节选
<configuration>
<configSections>
<section name="appSettings" type="System.Configuration.AppSettingsSection, System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" restartOnExternalChanges="false" requirePermission="false"/>
<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
private static volatile ConfigurationProperty s_propAppSettings;
private static volatile ConfigurationProperty s_propFile;
其跟App.config中映射的字段
ConfigurationProperty property = new ConfigurationProperty(null, typeof(KeyValueConfigurationCollection), null, ConfigurationPropertyOptions.IsDefaultCollection);
ConfigurationProperty property2 = new ConfigurationProperty("file", typeof(string), string.Empty, ConfigurationPropertyOptions.None);
s_propAppSettings = property;
2 s_propFile = property2;
属性暴露出来为:
file(attribute)
不作为元素:
[ConfigurationProperty("file", DefaultValue="")]
public string File
{
get
{
string str = (string) base[s_propFile];
if (str == null)
{
return string.Empty;
}
return str;
}
set
{
base[s_propFile] = value;
}
}
element:
[ConfigurationProperty("", IsDefaultCollection=true)]
public KeyValueConfigurationCollection Settings
{
get
{
return (KeyValueConfigurationCollection) base[s_propAppSettings];
}
}
对于不是嵌套的element,而是直接作为section的子节点集合,就照这样写,这样写没有在App.config的对应名字,看起来全是add元素(当然也可以有,后面会说明)
再来看看KeyValueConfigurationCollection这个集合继承自ConfigurationElementCollection
其中重要的两个方法:
protected override ConfigurationElement CreateNewElement()
{
return new KeyValueConfigurationElement();
} protected override object GetElementKey(ConfigurationElement element)
{
return ((KeyValueConfigurationElement) element).Key;
}
所以其实在每个Add中,Add的是KeyValueConfigurationElement,这个类的Key属性作为集合的关键字,再来看看KeyValueConfigurationElement类,这个类继承自ConfigurationElement
关键部分:
private static readonly ConfigurationProperty _propKey = new ConfigurationProperty("key", typeof(string), string.Empty, ConfigurationPropertyOptions.IsKey | Configurat ionPropertyOptions.IsRequired);
private static readonly ConfigurationProperty _propValue = new ConfigurationProperty("value", typeof(string), string.Empty, ConfigurationPropertyOptions.None); [ConfigurationProperty("key", Options=ConfigurationPropertyOptions.IsKey, DefaultValue="")]
public string Key
{
get
{
return (string) base[_propKey];
}
}
[ConfigurationProperty("value", DefaultValue="")]
public string Value
{
get
{
return (string) base[_propValue];
}
set
{
base[_propValue] = value;
}
}
具体到element的key,value了。这样我们也可以自定义节点了。
二.模仿appSettings做自己的setting
创建一个控制台应用和一个类库,在控制台中先添加system.configuration程序集的引用。然后我们写上自己想要的App.config的内容。如下
<?xml version="1.0" encoding="utf-8" ?>
<configuration> <Songs ChannelId="1">
<add name="1.mp3" length="100" />
<add name="2.mp3" length="100" />
<add name="3.mp3"/>
<add length="200"/>
</Songs> </configuration>
这样算是定义好了一些配置,其中有些song配置使用了默认的值。
但是为了使Songs这个Section工作起来,我们也需要像Appsettings一样添加自定义Section,我们添加 <configSections>元素,再在里面添加Section,添加好,完整如下
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="Songs" type="ConfigLib.SongsSection,ConfigLib"/>
</configSections> <Songs ChannelId="1">
<add name="1.mp3" length="100" />
<add name="2.mp3" length="100" />
<add name="3.mp3"/>
<addlength="200"/>
</Songs> </configuration>
其中ConfigLib为我们一开始添加的库的名字 ConfigLib.SongsSection为要映射到的类。
接下看看SongsSection类。
同样在ConfigLib这个Lib中添加system.configuration这个dll,然后使SongsSection这个类去继承ConfigurationSection类
namespace ConfigLib
{
public class SongsSection:ConfigurationSection
{
}
}
由于我们的appSettings的子节点都是数据的单个点,总共是一个集合,所以我们还要一个集合类用来存放所有的song.这个集合要继承ConfigurationElementCollection类
namespace ConfigLib
{
class Songcollection:ConfigurationElementCollection
{
}
}
但是这样是编译不过的,因为ConfigurationElementCollection类里有2个标注为abstract的方法需要我们子类来实现,先让它编译通过,如下
public class Songcollection:ConfigurationElementCollection
{
protected override ConfigurationElement CreateNewElement()
{
throw new NotImplementedException();
}
protected override object GetElementKey(ConfigurationElement element)
{
throw new NotImplementedException();
}
}
先不管实现,我们用这个Collection来装song.回到SongsSection类,我们可以使用上面的集合了,像appSettings那样,但要注意,我们为Songs这个Section添加了类似XML中属性(attribute)的channleid,由于这个不是Element,是个int类型(后面还有ConfigurationElement类),所以我们在类中属性(Property)中使用的时候这个的时候不会跑到element中去,它会乖乖在XML的属性位置。代码如下
namespace ConfigLib
{
public class SongsSection:ConfigurationSection
{
private readonly ConfigurationProperty collectionproperty = new ConfigurationProperty(null, typeof(Songcollection), null, ConfigurationPropertyOptions.IsDefaultCollection);
[ConfigurationProperty("",IsDefaultCollection=true)]
public Songcollection SongCollection
{
get
{
return (Songcollection)this[collectionproperty]; }
}
[ConfigurationProperty("ChannelId", IsKey = false, DefaultValue = "-1")]
public int ChannelId
{
get
{
return (int)this["ChannelId"];
}
}
}
}
其中SongCollection属性的写法很像appSettings的写法。
接下来看看Songcollection这个集合类最简单的写法:
namespace ConfigLib
{
public class Songcollection:ConfigurationElementCollection
{
protected override ConfigurationElement CreateNewElement()
{
return new SongElement();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((SongElement)element).Name;
} }
}
集合类的很多属性我们使用父类的,字面意思都比较好理解,其中GetElementKey是为这个集合指定关键字的,有点像数据库中的Key,这个Key不能重复,并且我们可以通过
这个Key获得集合中的元素(SongElement).
集合中主要是Element,Element基本就和XML中Element一样,SongElement这个类如下,用这个类(SongElement)定义的变量就是(app.config)XML中的Element,而不是Attribute,(类中的所有简单类型都在Attribute中出现)
namespace ConfigLib
{
public class SongElement:ConfigurationElement
{
[ConfigurationProperty("name",IsKey=true,DefaultValue="default.mp3")]
public string Name
{
get
{
return (string)this["name"];
}
}
[ConfigurationProperty("length", IsKey = false, DefaultValue = "-1")]
public int Length
{
get
{
return (int)this["length"];
}
}
}
}
为每个XML的attribute设置默认值,并且不为必须的,写App.config的时候保证Key(这里是歌的名字)不重复,如果需要通过索引访问song的集合,在集合中加如下索引器:
public SongElement this[int index]
{
get
{
return (SongElement)BaseGet(index);
}
}
由于集合是默认的AddClear类型,所以我们的XML元素(element)虽然存在,但是要写成add,clear形式,(如果有clear,clear写在哪,那么之前add过的元素就都不见了)
App.config还可以改成下面这样
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="Songs" type="ConfigLib.SongsSection,ConfigLib"/>
</configSections>
<Songs ChannelId="1">
<song name="1.mp3" length="100" />
<song name="2.mp3" length="100" />
<song name="3.mp3"/>
<song length="200"/>
</Songs>
</configuration>
把add改成了song,这样顺眼一点
那仅仅只要在集合类中添加:
protected override string ElementName
{
get
{
return "song";
}
}
public override ConfigurationElementCollectionType CollectionType
{
get
{
return ConfigurationElementCollectionType.BasicMap;
}
}
就可以了
如果App.config改为下面这样:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="Songs" type="ConfigLib.SongsSection,ConfigLib"/>
</configSections>
<Songs ChannelId="1">
<special_special_song specialsongname="special_1.mp3"/>
<specialsongs>
<specialsong specialsongname="special_2.mp3"/>
<specialsong specialsongname="special_3.mp3"/>
<specialsong specialsongname="special_4.mp3"/>
</specialsongs>
<song name="1.mp3" length="100" />
<song name="2.mp3" length="100" />
<song name="3.mp3"/>
<song length="200"/>
</Songs>
</configuration>
一样的道理,加一个SpecialSongElement类和容纳这个类的集合SpecialSongCollection,然后再在Section中做添加即可,在section类中,第一个
<special_special_song specialsongname="special_1.mp3"/>对应:
[ConfigurationProperty("special_special_song", IsKey = false)]
public SpecialSongElement SpecialSong
{
get
{
return (SpecialSongElement)this["special_special_song"];
}
}
而集合
<specialsongs>对应:
[ConfigurationProperty("specialsongs", IsKey = false, IsDefaultCollection = false)]
public SpecialSongCollection SpecialSongs
{
get
{
return (SpecialSongCollection)this["specialsongs"];
}
}
注意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的学习笔记的更多相关文章
- 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开发,未来实际工作应该会用到.未雨绸缪. 一.了解其系统层次架构 其系统分层四层,其具体例如以下: 第一层:Core OS watermark/ ...
- App.config
App.config的学习笔记 昨天基本弄清config的使用之后,再看WP的API,晕了.结果WP不支持system.configuration命名空间,这意味着想在WP上用App.config ...
- Beego学习笔记——Config
配置文件解析 这是一个用来解析文件的库,它的设计思路来自于database/sql,目前支持解析的文件格式有ini.json.xml.yaml,可以通过如下方式进行安装: go get github. ...
- Ruby学习笔记4: 动态web app的建立
Ruby学习笔记4: 动态web app的建立 We will first build the Categories page. This page contains topics like Art, ...
- go微服务框架kratos学习笔记五(kratos 配置中心 paladin config sdk [断剑重铸之日,骑士归来之时])
目录 go微服务框架kratos学习笔记五(kratos 配置中心 paladin config sdk [断剑重铸之日,骑士归来之时]) 静态配置 flag注入 在线热加载配置 远程配置中心 go微 ...
- 软件测试第六周学习笔记之“Win8 APP应用程序的白盒测试”
这周的学习笔记我想写点自己关于实验中碰到的问题和感想. 因为这次做的是白盒测试,所以我决定去测试一下上回测试的app的功能函数. 这次我用的是单元测试项目来做的白盒测试: 创建单元测试的步骤: 1.点 ...
- 高性能Cordova App开发学习笔记
高性能Cordova App开发学习笔记 文件结构 添加插件 构建准备 各个www的作用,prepare命令会将hello\www的内容会拷贝到platform下的wwww目录,知道该改哪里了吧?如果 ...
- PHP 开发 APP 接口 学习笔记与总结 - Redis 缓存
Redis 可以定期将数据备份到磁盘中(持久化),同时不仅仅支持简单的key/value 类型的数据,同时还提供list,set,hash等数据结构的存储:Memcache 只是简单的key/valu ...
随机推荐
- 剑指Offer:面试题6——重建二叉树(java实现)
问题描述:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不包含重复的数字. 例如: 输入:前序{1,2,4,7,3,5,6,8},中序{4,7,2,1 ...
- VS2015+win10+opencv3.0整个安装过程
LZ最近换了台新台式电脑,开始下载新VS软件,话说软件平台越新越好用,一看网上已经有VS2015版本,果断就去官网下载. 1.安装VS操作 官方网的链接如下:https://www.visualstu ...
- 一步一步学习Unity3d学习笔记系1.2 单机游戏和网游的数据验证概念
这一次的笔记的主要内容是单机和网游的数据存储,数据验证方式,在游戏的时候除了控制角色的行动,还涉及到用户角色的升级,经验,金钱赚取,道具购买,技能升级 等等一些数据的交易, 那么单机游戏和网游的区别如 ...
- php和apache安装心得
又一次安装apache和php~~ 又一次心碎的体验~ 本想参考之前的apache配置之间进行安装(在windows 下编辑,然后传到linux上),怎耐,一直有问题,打开浏览器直接进行下载.发现是浏 ...
- 学习总结 html 表格标签的使用
表格: <table></table>表格 width:宽度.可以用像素或百分比表示. 常用960像素. border:边框,常用值为0. cellpadding:内容跟边框的 ...
- ios项目记录
1,如何隐藏状态栏 在基类中重载UIViewController.h中的这个方法 - (BOOL)prefersStatusBarHidden { // iOS7后,[[UIApplication s ...
- sql server 2008 R2 配置开启远程访问
- 磁盘测试工具fio
https://wiki.mikejung.biz/Benchmarking #blocksize This options determines the block size for the I/O ...
- 关于Java中形参与实参的理解
今天阅读了一个写的非常棒的博文,通过此博文再次复习了Java中参数传递的知识(即值传递与引用传递的区别).参考网站http://www.cnblogs.com/binyue/p/3862276.htm ...
- 017Makefile工程管理
1.为什么需要Makefile? 利用Makefile和make的合作,可以把很多很多的工作合并成一个非常简单的命令:make: make能够使整个程序的编译.链接只需要一个命令(make)就可以完成 ...