一步一步教你玩转.NET Framework的配置文件app.config

  .NET中提供了几个和配置有关的类来支持用完
轻松的完成配置文件的读写设置:  System.Configuration.ConfigurationSectionGroup  一般和你项目中使用的Assambly保持1:1的对应关系,这样划分使得结构相对清晰,权责明确。当然你可以不使用它,这样一旦你的Assambly在别的地方要被重用时,找出相应的config信息就变得很困难。  System.Configuration.ConfigurationSection  维护一个相对独立的配置节,使用时需现在<ConfigSections></ConfigSections>节点下声明。我们熟悉的<appSettings></appSettings>以及<connectionStrings></connectionStrings/>就是.NET为我们预留的一个Section。  System.Configuration.ConfigurationElement
Collection & System.Configuration.ConfigurationElement  就是Section下具体的配置信息和配置信息的集合了。  下面
来看看怎么使用这些类玩转app.config  1.初级玩法  最初级的用法当然是使用<appSettings/>,我们在app.config 中添加:

<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>

  增加了一个单独的Section,名为"CustomSection",并且包含了我们创建的2个 configurationProperty。我们还可以继续作扩展,现在我们的config中section的部分呈现的是<CustomSection sectionId="1" sectionValue="The First Value" /> ,这样对于复杂的配置信息仍然不方便,我们是不是可以继续扩展,将其变成比较合理的:

<CustomSection>

<ChildCustomSectionA childId=1 childValue=”ChildA”></ChildCustomSectionA>

<ChildCustomSectionB childid=2 childValue=”ChildB”></ChildCustomSectionB>

</CustomSection>

  这种方式呢? 我们为<ChildCustomSectionA></ChildCustomSectionA>创建扩展自ConfigurationElement类的子类CustomSectionElementA,然后修改CustomSection类中的Property,使得类型不再是int 或 string,而是我们创建的新类CustomSectionElementA。

  由于ChildCustomSectionA 和ChildCustomSectionB 的结构相对一致,根据面向对象的开发封闭原则,我们可以先抽象出一个base类,然后让ChildCustomSectionA,ChildCustomSectionB分别继承自此base类,当以后要添加更多的ChildCustomSectionC,ChildCustomSectionD…时,使用这种Template的设计模式,将更加灵活。

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";

}

}

  完成了ConfigurationElement的实现,我们可以改写我们上一个例子中定义的CustomSection类了:

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

时间: 2024-11-04 16:58:40

一步一步教你玩转.NET Framework的配置文件app.config的相关文章

一步一步教你把自己的站点信息向alexa提交

alexa排名已经很强大有威信,各级站长以及广告主更加关注它,网赚站长也不例外,经常会去查一下网站的排名变化.在查询排名的过程中,发现自己网站的"网站简介"是:该站点还没有向alexa提交任何介绍信息;http://www.aliyun.com/zixun/aggregation/32466.html">网站站长: 不详;联系邮箱: 不详等,可想而知,这会让每个认真做站的站长很郁闷.虽然alexa已经推出中文版,但提交或更新网站还需要在官方英文站点下进行,而且提交步骤与

一步一步教你加密解密技术——软件保护技术(1)(1)

第6章 软件保护技术第一节 常见保护技巧1.序列号方式(1)序列号保护机制数学算法一项都是密码加密的核心,但在一般的软件加密中,它似乎并不太为人们关心,因为大多数时候软件加密本身实现的都是一种编程的技巧.但近几年来随着序列号加密程序的普及,数学算法在软件加密中的比重似乎是越来越大了. 我们先来看看在网络上大行其道的序列号加密的工作原理.当用户从网络上下载某个shareware--共享软件后,一般都有使用时间上的限制,当过了共享软件的试用期后,你必须到这个软件的公司去注册后方能继续使用.注册过程一

一步一步教你加密解密技术——压缩与脱壳(1)(1)

压缩与脱壳第一节 PE文件格式PE教程1: PE文件格式一览PE 的意思就是 Portable Executable(可移植的执行体).它是 Win32环境自身所带的执行体文件格式.它的一些特性继承自 Unix的 Coff (common object file format)文件格式."portable executable"(可移植的执行体)意味着此文件格式是跨win32平台的 : 即使Windows运行在非Intel的CPU上,任何win32平台的PE装载器都能识别和使用该文件格

一步一步教你加密解密技术——动态分析技术(1)

第2章 动态分析技术第一节 SoftICE与TRW2000安装安装与配制SOFTICE有几个平台的版本,DOS,WINDOWS 3.0,Windows 95/98,WINDOWS NT,等. 由于现在最普及的操作系统是 Windows 95/98.Windows NT.Windows Millennium.Windows2000因此就讲讲SOFTICE在这几个平台安装时的一些注意事项.一.SOFTICE for win9x安装与配制㈠.SOFTICE安装 1.SOFTICE目前最新版本是4.05

一步一步详细地教你如何正确地提交ALEXA

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 谨以此篇献给千千万万的还没有向ALEXA提交任何介绍信息的站长.我刚接触站长这个职业,我的小站也是前天才上线,希望大家多支持. 目前ALEXA排名是比较热门的话题,大大小小的站长都对这个东西很关注,我也不例外,每天都会去查一下网站的排名变化, 不过在查ALEXA排名时,我经常去chinaz的站长工具那里查询,一是因为速度快,二呢,感觉他那里查

一步一步教你加密解密技术——压缩与脱壳(3)(1)

第四节 手动脱壳1.基本知识手动脱壳就是不 借助自动脱壳工具,而是用动态调试工具SOFTICE或TRW2000来脱壳.这课谈谈一些入门方面的知识,如要了解更深的脱壳知识,请参考<脱壳高级篇>这课.工具*调试器:SoftICE .TRW2000*内存抓取工具:Procdump等:*十六进制工具:Hiew.UltraEdit.Hex Workshop等:*PE编辑工具: Procdump.PEditor等:名词概念★PE文件:Microsoft设计了一种新的文件格式Portable Executa

一步一步教你加密解密技术——函数、资源与注册表(1)

第4章 函数.资源与注册表第一节 Win32 API 函数1.限制程序功能函数1.EnableMenuItem允许.禁止或变灰指定的菜单条目2.EnableWindow允许或禁止鼠标和键盘控制指定窗口和条目(禁止时菜单变灰) 2.对话框函数CreateDialog从资源模板建立一非模态对话窗CreateDialogParam 从资源模板建立一非模态对话窗CreateDialogIndirect 从内存模板建立一非模态对话窗CreateDialogIndirectParam从内存模板建立一非模态对

一步一步教你网站同步镜像(转载)_Mysql

1.介绍 现在的网站随着访问量的增加,单一服务器无法承担巨大的访问量,有没有什么方便快捷的方式解决这个问题呢,答案是"有"!比如建立服务器群,进行均衡负载. 但是如果要解决像电信网通这样的互访问题(中国网民的悲哀..),这个解决办法就无能为了了! 要解决这个问题最方便快捷的方式就是建立镜像网站!由访问者自己选择适合自己网络的速度最快的网站!这样即可以解决线路问题,又可以解决访问量问题! 2.网站同步的数据分类 网站数据基本分为两类: 一类是文件,比如HTML,ASP,PHP等网页文件,

优步拼车暗号怎么玩 优步拼车暗号优惠怎么得?

优步拼车暗号怎么玩 第一步:查短信,看暗号 你的拼车暗号在小U昨天发送的短信中- 如果短信已删除,在app"通知"栏看推送,你的拼车暗号在头条 第二步:问车主,对暗号 车主也有拼车暗号 你的暗号+车主暗号=今日优惠码! 举个栗子 你的暗号:炸鸡 车主的暗号:啤酒 于是今天的优惠码就是炸鸡啤酒 第三步:问拼友,拼优惠 小U每天会放出多组暗号 说不定,你的拼友和你的暗号不一样! 试试拼起来 你的优惠码+拼友的优惠码=超级优惠码 更大优惠Get! 举个栗子 你的优惠码:啤酒炸鸡 拼友的优惠码