一步一步教你玩转.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实现一个简单的基 ...
随机推荐
- [Hadoop] Sqoop安装过程详解
Sqoop是一个用来将Hadoop和关系型数据库中的数据相互转移的工具,可以将一个关系型数据库(例如 : MySQL ,Oracle ,Postgres等)中的数据导进到Hadoop的HDFS中,也可 ...
- 【机器学习】迭代决策树GBRT(渐进梯度回归树)
一.决策树模型组合 单决策树C4.5由于功能太简单,并且非常容易出现过拟合的现象,于是引申出了许多变种决策树,就是将单决策树进行模型组合,形成多决策树,比较典型的就是迭代决策树GBRT和随机森林RF. ...
- linux 下jansson安装和使用
1.安装jansson ./configure make make install 2.生成帮助文档 cd doc make html 编译安装doc时提示 spinx-build not a com ...
- maven工程导入eclipse后报错
原因:需要重新部署下tomcat环境 解决方式: 右击->属性:
- go实现冒泡排序和快速排序
项目结构 冒泡排序算法,源文件bubblesort.go package bubblesort // 冒泡排序 func BubbleSort(values []int) { for i := 0; ...
- 使用军哥的lnmp配置虚拟主机,需要注意的是要配置hosts文件
#使用军哥的lnmp配置虚拟主机,需要注意的是要配置hosts文件(这一点官方没有讲到)具体方法:1.修改hosts文件sudo vim /etc/hosts 2.在hosts文件中新增一行(这里类似 ...
- 图像像素灰度内插(Matlab实现)
常用的像素灰度内插法:最近邻元法.双线性内插法.三次内插法 %%像素灰度内插 factor = 0.75;%缩放比 u = 0.6;v = 0.7; itp1 = uint8(zeros(ceil(h ...
- Windows服务器初始配置
系统状态是否良好 检查ip地址.子网掩码等配置 防火墙是否关闭 是否有攻击,有多大的攻击,什么类型的攻击,攻击流量图 是否中病毒 1.改端口 (1)打开注册表 [HKEY_LOCAL_MACHINE\ ...
- JavaWeb案例:上次访问时间 Cookie技术
package cn.itcast.access; import javax.servlet.ServletException; import javax.servlet.annotation.Web ...
- Roslyn 编译器和RyuJIT 编译器
Roslyn 编译器 https://msdn.microsoft.com/zh-cn/library/mt162308.aspx https://blogs.msdn.microsoft.com/d ...