一步一步教你玩转.NET Framework的配置文件app.config
转自https://www.cnblogs.com/tonnie/archive/2010/12/17/appconfig.html
<configuration>
<appSettings>
<add key="MyConfigString" value="Test Config Data"/>
</appSettings>
</configuration>
public class AppSettingConfig
{
public string resultValue;
public AppSettingConfig()
{
this.resultValue = ConfigurationManager.AppSettings["MyConfigString"].ToString();
}
}
[TestMethod]
public void TestAppSettingConfigNode()
{
AppSettingConfig appCon = new AppSettingConfig();
Assert.AreEqual("Test Config Data", appCon.resultValue);
}
没有问题!
我们加个Section来看看如何访问:
<configuration>
<configSections>
<sectionGroup name="MySectionGroup">
<section name="MyFirstSection" type="System.Configuration.DictionarySectionHandler"/>
<section name="MySecondSection" type="System.Configuration.DictionarySectionHandler"/>
</sectionGroup> </configSections>
<MySectionGroup>
<MyFirstSection>
<add key="First" value="First Section"/>
</MyFirstSection>
<MySecondSection>
<add key="Second" value="Second Section"/>
</MySecondSection>
</MySectionGroup>
</configuration>
注意我们在section的type中给出了System.Configuration.DictionarySectionHandler,这也限制了我们在具体的ConfigurationElement中只能使用<add key=”” value=””/>的形式,使得我们GetSection()方法返回的是一个IDictory对象,我们可以根据Key来取得相应的值
public class SectionConfig
{
public string resultValue;
public SectionConfig()
{
System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); IDictionary dic = ConfigurationManager.GetSection("MySectionGroup/MySecondSection") as IDictionary;
this.resultValue = dic["Second"].ToString(); }
}
[TestMethod]
public void TestSectionGroupConfigNode()
{
SectionConfig sc = new SectionConfig();
Assert.AreEqual("First Section", sc.resultValue);
}
还是没问题。
2. 中级玩法
.NET支持对上述提到的configuration类进行扩展,我们可以定义自己的Section。
继承自基类System.Configuration.ConfigurationSection,ConfigurationSection已经提供了索引器用来获取设置数据。
在类中加上ConfigurationProperty属性来定义Section中的Element:
public class CustomSection:System.Configuration.ConfigurationSection
{
[ConfigurationProperty("sectionId", IsRequired=true, IsKey=true)]
public int SectionId {
get { return (int)base["sectionId"]; }
set { base["sectionId"] = value; }
} [ConfigurationProperty("sectionValue", IsRequired = false)]
public string SectionValue {
get { return base["sectionValue"].ToString(); }
set { base["sectionValue"] = value; }
}
}
操作此Section,我们将其动态加入app.config中,并读出来:
public class CustomSectionBroker
{
private CustomSection customSection = null;
public void InsertCustomSection()
{
customSection = new CustomSection();
customSection.SectionId = 1;
customSection.SectionValue = "The First Value";
System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
config.Sections.Add("CustomSection", customSection);
config.Save(ConfigurationSaveMode.Minimal);
} public int GetCustomSectionID()
{
System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
CustomSection cs = config.GetSection("CustomSection") as CustomSection;
return cs.SectionId;
}
} [TestMethod]
public void TestCustomSection()
{
CustomSectionBroker cb = new CustomSectionBroker();
cb.InsertCustomSection();
Assert.AreEqual(1, cb.GetCustomSectionID());
}
可以看下现在app.config文件的变化:
<configuration>
<configSections>
<section name="CustomSection" type="Tonnie.Configuration.Library.CustomSection, Tonnie.Configuration.Library, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<sectionGroup name="MySectionGroup">
<section name="MyFirstSection" type="System.Configuration.DictionarySectionHandler"/>
<section name="MySecondSection" type="System.Configuration.DictionarySectionHandler"/>
</sectionGroup> </configSections>
<CustomSection sectionId="1" sectionValue="The First Value" />
<MySectionGroup>
<MyFirstSection>
<add key="First" value="First Section"/>
</MyFirstSection>
<MySecondSection>
<add key="Second" value="Second Section"/>
</MySecondSection>
</MySectionGroup>
</configuration>
public abstract class CustomSectionElementBase:System.Configuration.ConfigurationElement
{
[ConfigurationProperty("childId", IsRequired=true, IsKey=true)]
public int ChildID
{
get{return (int)base["childId"];}
set{base["childId"] = value;}
} [ConfigurationProperty("childValue", IsRequired=true)]
public string ChildValue
{
get{return base["childValue"].ToString();}
set{base["childValue"] = value;}
}
} public class CustomSectionElementA:CustomSectionElementBase
{
public CustomSectionElementA()
{
base.ChildID = 1;
base.ChildValue = "ChildA";
}
}
public class CustomSectionElementB:CustomSectionElementBase
{
public CustomSectionElementB()
{
base.ChildID = 2;
base.ChildValue = "ChildB";
}
}
public class CustomSectionWithChildElement:System.Configuration.ConfigurationSection
{
private const string elementChildA = "childSectionA";
private const string elementChildB = "childSectionB"; [ConfigurationProperty(elementChildA, IsRequired=true, IsKey=true)]
public CustomSectionElementA ChildSectionA {
get { return base[elementChildA] as CustomSectionElementA; }
set { base[elementChildA] = value; }
} [ConfigurationProperty(elementChildB, IsRequired = true)]
public CustomSectionElementB ChildSectionB {
get { return base[elementChildB] as CustomSectionElementB; }
set { base[elementChildB] = value; }
}
} public class CustomSectionWithChildElementBroker
{
private CustomSectionWithChildElement customSection = null;
public void InsertCustomSection()
{
customSection = new CustomSectionWithChildElement();
customSection.ChildSectionA = new CustomSectionElementA();
customSection.ChildSectionB= new CustomSectionElementB(); System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
config.Sections.Add("CustomSectionWithChildElement", customSection);
config.Save(ConfigurationSaveMode.Minimal);
} public int GetCustomSectionChildAID()
{
System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
CustomSectionWithChildElement cswe = config.GetSection("CustomSectionWithChildElement") as CustomSectionWithChildElement;
return cswe.ChildSectionA.ChildID;
}
}
红色字体就是修改的地方了,将Property改成我们自定义类的形式.测试代码如下:
[TestMethod]
public void TestCustomSectionWithChildElement()
{
CustomSectionWithChildElementBroker cweb = new CustomSectionWithChildElementBroker();
cweb.InsertCustomSection();
Assert.AreEqual(1, cweb.GetCustomSectionChildAID());
}
看看运行后我们的app.config变成什么样子了:
<configuration>
<configSections>
<section name="CustomSectionWithChildElement" type="Tonnie.Configuration.Library.CustomSectionWithChildElement, Tonnie.Configuration.Library, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<section name="CustomSection" type="Tonnie.Configuration.Library.CustomSection, Tonnie.Configuration.Library, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<sectionGroup name="MySectionGroup">
<section name="MyFirstSection" type="System.Configuration.DictionarySectionHandler"/>
<section name="MySecondSection" type="System.Configuration.DictionarySectionHandler"/>
</sectionGroup> </configSections>
<CustomSectionWithChildElement>
<childSectionA childId="1" childValue="ChildA" />
<childSectionB childId="2" childValue="ChildB" />
</CustomSectionWithChildElement>
<CustomSection sectionId="1" sectionValue="The First Value" />
<MySectionGroup>
<MyFirstSection>
<add key="First" value="First Section"/>
</MyFirstSection>
<MySecondSection>
<add key="Second" value="Second Section"/>
</MySecondSection>
</MySectionGroup>
</configuration>
cool,好像完成了我们的要求。
下面为我们的CustomSectionWithChildElement外面再加一层SectionGroup.
public class CustomSectionGroup : System.Configuration.ConfigurationSectionGroup
{
[ConfigurationProperty("customSectionA", IsRequired = true, IsKey = true)]
public CustomSectionWithChildElement SectionA
{
get { return base.Sections["customSectionA"] as CustomSectionWithChildElement; }
set
{
this.Sections.Add("customSectionA", value);
}
}
}
public class CustomSectionGroupWithChildElementBroker
{
private CustomSectionWithChildElement customSection = null;
public void InsertCustomSectionGroup()
{
customSection = new CustomSectionWithChildElement();
customSection.ChildSectionA = new CustomSectionElementA();
customSection.ChildSectionB= new CustomSectionElementB(); CustomSectionGroup sectionGroup = new CustomSectionGroup();
System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
if (config.GetSectionGroup("customSectionGroup") == null)
config.SectionGroups.Add("customSectionGroup",sectionGroup);
sectionGroup.SectionA = customSection;
config.Save(ConfigurationSaveMode.Minimal);
} public int GetCustomSectionChildAID()
{
System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); CustomSectionWithChildElement cswe = config.GetSection("customSectionGroup/customSectionA") as CustomSectionWithChildElement;
return cswe.ChildSectionA.ChildID;
}
}
测试一下:
[TestMethod]
public void TestCustomSectionGroupWithChildElement()
{
CustomSectionGroupWithChildElementBroker cweb = new CustomSectionGroupWithChildElementBroker();
cweb.InsertCustomSectionGroup();
Assert.AreEqual(1, cweb.GetCustomSectionChildAID());
}
没问题,看下现在的app.config,是不是更加结构化了:
<configuration>
<configSections>
<sectionGroup name="MySectionGroup">
<section name="MyFirstSection" type="System.Configuration.DictionarySectionHandler"/>
<section name="MySecondSection" type="System.Configuration.DictionarySectionHandler"/>
</sectionGroup> <sectionGroup name="customSectionGroup" type="Tonnie.Configuration.Library.CustomSectionGroup, Tonnie.Configuration.Library, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" >
<section name="customSectionA" type="Tonnie.Configuration.Library.CustomSectionWithChildElement, Tonnie.Configuration.Library, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</sectionGroup>
</configSections>
<MySectionGroup>
<MyFirstSection>
<add key="First" value="First Section"/>
</MyFirstSection>
<MySecondSection>
<add key="Second" value="Second Section"/>
</MySecondSection>
</MySectionGroup>
<customSectionGroup>
<customSectionA>
<childSectionA childId="1" childValue="ChildA" />
<childSectionB childId="2" childValue="ChildB" />
</customSectionA>
</customSectionGroup>
</configuration>
3 高级玩法
到目前为止可能大家对app.config有了一定的认识了,我们自己可以不断的去扩展.NET Framework提供给我们的类,从SectionGroup,Section,ElementCollection,Element 从上自下的一级一级的组装成符合工程化项目配置文件需要的形式。当遇到可能配置元素的类型属性差不多时,可以抽象出一个base类来。比如可以抽象出Section这一层面的base类,或者ElementCollection,Element这一层的抽象类(可以是抽象的泛型类)来。同时增加泛型来更好的支持扩展。具体例子下次再给了。
附上所有代码:/Files/tonnie/Tonnie.Configuration.rar
一点点心得,欢迎交流……
一步一步教你玩转.NET Framework的配置文件app.config的更多相关文章
- 一步一步教你如何在linux下配置apache+tomcat(转)
一步一步教你如何在linux下配置apache+tomcat 一.安装前准备. 1. 所有组件都安装到/usr/local/e789目录下 2. 解压缩命令:tar —vxzf 文件名(. ...
- 一步一步教你将普通的wifi路由器变为智能广告路由器
一步一步教你将普通的wifi路由器变为智能广告路由器 相信大家对WiFi智能广告路由器已经不再陌生了,现在很多公共WiFi上网,都需要登录并且验证,这也就是WiFi广告路由器的最重要的功能.大致就是下 ...
- 一步一步教你使用Git
一步一步教你使用Git 互联网给我们带来方便的同时,也时常让我们感到困惑.随便搜搜就出一大堆结果,然而总是有大量的重复和错误.小妖发出的内容,都是自己实测过的,有问题请留言. 现在,你已经安装了Git ...
- 使用WPF教你一步一步实现连连看
使用WPF教你一步一步实现连连看(一) 第一步: 问题,怎样动态的建立一个10*10的grid(布局) for (int i = 0; i < 10; i++){ RowDefinition r ...
- 一步一步教你用 Vue.js + Vuex 制作专门收藏微信公众号的 app
一步一步教你用 Vue.js + Vuex 制作专门收藏微信公众号的 app 转载 作者:jrainlau 链接:https://segmentfault.com/a/1190000005844155 ...
- Ace教你一步一步做Android新闻客户端(一)
复制粘贴了那么多博文很不好意思没点自己原创的也说不出去,现在写一篇一步一步教你做安卓新闻客户端,借此机会也是让自己把相关的技术再复习一遍,大神莫笑,专门做给新手看. 手里存了两篇,一个包括软件视图 和 ...
- 一步一步教你实现iOS音频频谱动画(二)
如果你想先看看最终效果再决定看不看文章 -> bilibili 示例代码下载 第一篇:一步一步教你实现iOS音频频谱动画(一) 本文是系列文章中的第二篇,上篇讲述了音频播放和频谱数据计算,本篇讲 ...
- 一步一步教你实现iOS音频频谱动画(一)
如果你想先看看最终效果再决定看不看文章 -> bilibili 示例代码下载 第二篇:一步一步教你实现iOS音频频谱动画(二) 基于篇幅考虑,本次教程分为两篇文章,本篇文章主要讲述音频播放和频谱 ...
- 通过Dapr实现一个简单的基于.net的微服务电商系统(四)——一步一步教你如何撸Dapr之订阅发布
之前的章节我们介绍了如何通过dapr发起一个服务调用,相信看过前几章的小伙伴已经对dapr有一个基本的了解了,今天我们来聊一聊dapr的另外一个功能--订阅发布 目录:一.通过Dapr实现一个简单的基 ...
随机推荐
- SSO跨域 CodeProject
http://www.codeproject.com/Articles/114484/Single-Sign-On-SSO-for-cross-domain-ASP-NET-appl 翻译: http ...
- Eclipse插件:tomcatPluginV33.zip 安装
一.下载 地址:http://www.eclipsetotale.com/tomcatPlugin.html 二.安装 1.解压tomcatPluginV33.zip到Eclipse的\feature ...
- VMware10中安装centos7没有可用的网络设备
1.问题描述 centos7安装到虚拟机无法上网 2.安装环境 win7 x64 WM 10.01 iso CentOS-7-x86_64-DVD-1503-01.iso {4.01G} ...
- MySQL之创、增、删、改、查
MySQL Select version(); 当前服务器版本 Select database(); 查看当前工作数据库 Show databases; 显示所有数据库 Select user ...
- java之字符串转换
参考http://how2j.cn/k/number-string/number-string-parse/317.html 数字转字符串 方法1: 使用String类的静态方法valueOf 方法2 ...
- 廖雪峰的java教程
F:\教程\0-免费下载-廖雪峰 公司电脑地址: G:\学习中\廖雪峰的java教程 廖雪峰java课程地址: https://www.feiyangedu.com/category/JavaSE 0 ...
- 数据库路由中间件MyCat - 源代码篇(17)
此文已由作者张镐薪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 调用processInsert(sc,schema,sqlType,origSQL,tableName,pr ...
- Swoole HTTP 的应用
目录 概述 代码 小结 扩展 概述 这是关于 Swoole 学习的第四篇文章:Swoole HTTP 的应用. 第三篇:Swoole WebSocket 的应用 第二篇:Swoole Task 的应用 ...
- PHP之递归函数
https://www.cnsecer.com/4146.html http://www.jb51.net/article/71424.htm //一列数字的规则如下:1,1,2,3,5,8,13,2 ...
- poj1088滑雪最短路径
滑雪 Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 97281 Accepted: 36886 Description ...