在一般的项目中,为了使你的代码更加灵活,更方便调整,减少不必要的hard code,我们都在config中添加许多配置信息,一般可以选择.NET自带的配置文件形式app.config或者web项目中的web.config来完成配置工作。
.NET中提供了几个和配置有关的类来支持用完轻松的完成配置文件的读写设置:
System.Configuration.ConfigurationSectionGroup
一般和你项目中使用的Assambly保持1:1的对应关系,这样划分使得结构相对清晰,权责明确。当然你可以不使用它,这样一旦你的Assambly在别的地方要被重用时,找出相应的config信息就变得很困难。
System.Configuration.ConfigurationSection
维护一个相对独立的配置节,使用时需现在<ConfigSections></ConfigSections>节点下声明。我们熟悉的<appSettings></appSettings>以及<connectionStrings></connectionStrings/>就是.NET为我们预留的一个Section。
System.Configuration.ConfigurationElementCollection & System.Configuration.ConfigurationElement
就是Section下具体的配置信息和配置信息的集合了。
 
下面来看看怎么使用这些类玩转app.config
 
1.初级使用
 
最初级的用法当然是使用<appSettings/>,我们在app.config 中添加
  1. <configuration>
  2. <appSettings>
  3. <add key="MyConfigString" value="Test Config Data"/>
  4. </appSettings>
  5. </configuration>
访问它
  1.   public class AppSettingConfig
  2. {
  3. public string resultValue;
  4. public AppSettingConfig()
  5. {
  6. this.resultValue = ConfigurationManager.AppSettings["MyConfigString"].ToString();
  7. }
  8. }
  9. [TestMethod]
  10. public void TestAppSettingConfigNode()
  11. {
  12. AppSettingConfig appCon = new AppSettingConfig();
  13. Assert.AreEqual("Test Config Data", appCon.resultValue);
  14. }
  1. 没有问题!
  1.  
  1. 我们加个Section来看看如何访问:
  1. <configuration>
  2. <configSections>
  3. <sectionGroup name="MySectionGroup">
  4. <section name="MyFirstSection" type="System.Configuration.DictionarySectionHandler"/>
  5. <section name="MySecondSection" type="System.Configuration.DictionarySectionHandler"/>
  6. </sectionGroup>
  7.  
  8. </configSections>
  9. <MySectionGroup>
  10. <MyFirstSection>
  11. <add key="First" value="First Section"/>
  12. </MyFirstSection>
  13. <MySecondSection>
  14. <add key="Second" value="Second Section"/>
  15. </MySecondSection>
  16. </MySectionGroup>
  17. </configuration>
  1. 注意我们在sectiontype中给出了System.Configuration.DictionarySectionHandler,这也限制了我们在具体的ConfigurationElement中只能使用<add key=”” value=””/>的形式,使得我们GetSection()方法返回的是一个IDictory对象,我们可以根据Key来取得相应的值
  1.  
  1.   public class SectionConfig
  2. {
  3. public string resultValue;
  4. public SectionConfig()
  5. {
  6. System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
  7.  
  8. IDictionary dic = ConfigurationManager.GetSection("MySectionGroup/MySecondSection") as IDictionary;
  9. this.resultValue = dic["Second"].ToString();
  10.  
  11. }
  12. }
  13. [TestMethod]
  14. public void TestSectionGroupConfigNode()
  15. {
  16. SectionConfig sc = new SectionConfig();
  17. Assert.AreEqual("First Section", sc.resultValue);
  18. }
  1. 还是没问题。
  1. 2. 中级使用
  1. .NET支持对上述提到的configuration类进行扩展,我们可以定义自己的Section
  1. 继承自基类System.Configuration.ConfigurationSectionConfigurationSection已经提供了索引器用来获取设置数据。
  1. 在类中加上ConfigurationProperty属性来定义Section中的Element
  1.  
  1.   public class CustomSection:System.Configuration.ConfigurationSection
  2. {
  3. [ConfigurationProperty("sectionId", IsRequired=true, IsKey=true)]
  4. public int SectionId {
  5. get { return (int)base["sectionId"]; }
  6. set { base["sectionId"] = value; }
  7. }
  8.  
  9. [ConfigurationProperty("sectionValue", IsRequired = false)]
  10. public string SectionValue {
  11. get { return base["sectionValue"].ToString(); }
  12. set { base["sectionValue"] = value; }
  13. }
  14. }
  1. 操作此Section,我们将其动态加入app.config中,并读出来:
  1.    public class CustomSectionBroker
  2. {
  3. private CustomSection customSection = null;
  4. public void InsertCustomSection()
  5. {
  6. customSection = new CustomSection();
  7. customSection.SectionId = ;
  8. customSection.SectionValue = "The First Value";
  9. System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
  10. config.Sections.Add("CustomSection", customSection);
  11. config.Save(ConfigurationSaveMode.Minimal);
  12. }
  13.  
  14. public int GetCustomSectionID()
  15. {
  16. System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
  17. CustomSection cs = config.GetSection("CustomSection") as CustomSection;
  18. return cs.SectionId;
  19. }
  20. }
  21.  
  22.   [TestMethod]
  23.   public void TestCustomSection()
  24.   {
  25.   CustomSectionBroker cb = new CustomSectionBroker();
  26.   cb.InsertCustomSection();
  27.   Assert.AreEqual(, cb.GetCustomSectionID());
  28.   }
  1. 可以看下现在app.config文件的变化:
  1. <configuration>
  2. <configSections>
  3. <section name="CustomSection" type="Tonnie.Configuration.Library.CustomSection, Tonnie.Configuration.Library, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
  4. <sectionGroup name="MySectionGroup">
  5. <section name="MyFirstSection" type="System.Configuration.DictionarySectionHandler"/>
  6. <section name="MySecondSection" type="System.Configuration.DictionarySectionHandler"/>
  7. </sectionGroup>
  8.  
  9. </configSections>
  10. <CustomSection sectionId="" sectionValue="The First Value" />
  11. <MySectionGroup>
  12. <MyFirstSection>
  13. <add key="First" value="First Section"/>
  14. </MyFirstSection>
  15. <MySecondSection>
  16. <add key="Second" value="Second Section"/>
  17. </MySecondSection>
  18. </MySectionGroup>
  19. </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的设计模式,将更加灵活。
  1.    public abstract class CustomSectionElementBase:System.Configuration.ConfigurationElement
  2. {
  3. [ConfigurationProperty("childId", IsRequired=true, IsKey=true)]
  4. public int ChildID
  5. {
  6. get{return (int)base["childId"];}
  7. set{base["childId"] = value;}
  8. }
  9.  
  10. [ConfigurationProperty("childValue", IsRequired=true)]
  11. public string ChildValue
  12. {
  13. get{return base["childValue"].ToString();}
  14. set{base["childValue"] = value;}
  15. }
  16. }
  17.  
  18. public class CustomSectionElementA:CustomSectionElementBase
  19. {
  20. public CustomSectionElementA()
  21. {
  22. base.ChildID = ;
  23. base.ChildValue = "ChildA";
  24. }
  25. }
  26. public class CustomSectionElementB:CustomSectionElementBase
  27. {
  28. public CustomSectionElementB()
  29. {
  30. base.ChildID = ;
  31. base.ChildValue = "ChildB";
  32. }
  33. }
完成了ConfigurationElement的实现,我们可以改写我们上一个例子中定义的CustomSection类了:
 
  1.   public class CustomSectionWithChildElement:System.Configuration.ConfigurationSection
  2. {
  3. private const string elementChildA = "childSectionA";
  4. private const string elementChildB = "childSectionB";
  5.  
  6. [ConfigurationProperty(elementChildA, IsRequired=true, IsKey=true)]
  7. public CustomSectionElementA ChildSectionA {
  8. get { return base[elementChildA] as CustomSectionElementA; }
  9. set { base[elementChildA] = value; }
  10. }
  11.  
  12. [ConfigurationProperty(elementChildB, IsRequired = true)]
  13. public CustomSectionElementB ChildSectionB {
  14. get { return base[elementChildB] as CustomSectionElementB; }
  15. set { base[elementChildB] = value; }
  16. }
  17. }
  18.  
  19. public class CustomSectionWithChildElementBroker
  20. {
  21. private CustomSectionWithChildElement customSection = null;
  22. public void InsertCustomSection()
  23. {
  24. customSection = new CustomSectionWithChildElement();
  25. customSection.ChildSectionA = new CustomSectionElementA();
  26. customSection.ChildSectionB= new CustomSectionElementB();
  27.  
  28. System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
  29. config.Sections.Add("CustomSectionWithChildElement", customSection);
  30. config.Save(ConfigurationSaveMode.Minimal);
  31. }
  32.  
  33. public int GetCustomSectionChildAID()
  34. {
  35. System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
  36. CustomSectionWithChildElement cswe = config.GetSection("CustomSectionWithChildElement") as CustomSectionWithChildElement;
  37. return cswe.ChildSectionA.ChildID;
  38. }
  39. }
  1. 红色字体就是修改的地方了,将Property改成我们自定义类的形式.测试代码如下:
  1.      [TestMethod]
  2. public void TestCustomSectionWithChildElement()
  3. {
  4. CustomSectionWithChildElementBroker cweb = new CustomSectionWithChildElementBroker();
  5. cweb.InsertCustomSection();
  6. Assert.AreEqual(, cweb.GetCustomSectionChildAID());
  7. }

看看运行后我们的app.config变成什么样子了:

  1. <configuration>
  2. <configSections>
  3. <section name="CustomSectionWithChildElement" type="Tonnie.Configuration.Library.CustomSectionWithChildElement, Tonnie.Configuration.Library, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
  4. <section name="CustomSection" type="Tonnie.Configuration.Library.CustomSection, Tonnie.Configuration.Library, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
  5. <sectionGroup name="MySectionGroup">
  6. <section name="MyFirstSection" type="System.Configuration.DictionarySectionHandler"/>
  7. <section name="MySecondSection" type="System.Configuration.DictionarySectionHandler"/>
  8. </sectionGroup>
  9.  
  10. </configSections>
  11. <CustomSectionWithChildElement>
  12. <childSectionA childId="" childValue="ChildA" />
  13. <childSectionB childId="" childValue="ChildB" />
  14. </CustomSectionWithChildElement>
  15. <CustomSection sectionId="" sectionValue="The First Value" />
  16. <MySectionGroup>
  17. <MyFirstSection>
  18. <add key="First" value="First Section"/>
  19. </MyFirstSection>
  20. <MySecondSection>
  21. <add key="Second" value="Second Section"/>
  22. </MySecondSection>
  23. </MySectionGroup>
  24. </configuration>

cool,好像完成了我们的要求。

下面为我们的CustomSectionWithChildElement外面再加一层SectionGroup.

  1.   public class CustomSectionGroup : System.Configuration.ConfigurationSectionGroup
  2. {
  3. [ConfigurationProperty("customSectionA", IsRequired = true, IsKey = true)]
  4. public CustomSectionWithChildElement SectionA
  5. {
  6. get { return base.Sections["customSectionA"] as CustomSectionWithChildElement; }
  7. set
  8. {
  9. this.Sections.Add("customSectionA", value);
  10. }
  11. }
  12. }
  13.  
  14.   public class CustomSectionGroupWithChildElementBroker
  15. {
  16. private CustomSectionWithChildElement customSection = null;
  17. public void InsertCustomSectionGroup()
  18. {
  19. customSection = new CustomSectionWithChildElement();
  20. customSection.ChildSectionA = new CustomSectionElementA();
  21. customSection.ChildSectionB= new CustomSectionElementB();
  22.  
  23. CustomSectionGroup sectionGroup = new CustomSectionGroup();
  24. System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
  25. if (config.GetSectionGroup("customSectionGroup") == null)
  26. config.SectionGroups.Add("customSectionGroup",sectionGroup);
  27. sectionGroup.SectionA = customSection;
  28. config.Save(ConfigurationSaveMode.Minimal);
  29. }
  30.  
  31. public int GetCustomSectionChildAID()
  32. {
  33. System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
  34.  
  35. CustomSectionWithChildElement cswe = config.GetSection("customSectionGroup/customSectionA") as CustomSectionWithChildElement;
  36. return cswe.ChildSectionA.ChildID;
  37. }
  38. }
  1. 测试一下:
  1.      [TestMethod]
  2. public void TestCustomSectionGroupWithChildElement()
  3. {
  4. CustomSectionGroupWithChildElementBroker cweb = new CustomSectionGroupWithChildElementBroker();
  5. cweb.InsertCustomSectionGroup();
  6. Assert.AreEqual(, cweb.GetCustomSectionChildAID());
  7. }
  1. 没问题,看下现在的app.config,是不是更加结构化了:
  1. <configuration>
  2. <configSections>
  3. <sectionGroup name="MySectionGroup">
  4. <section name="MyFirstSection" type="System.Configuration.DictionarySectionHandler"/>
  5. <section name="MySecondSection" type="System.Configuration.DictionarySectionHandler"/>
  6. </sectionGroup>
  7.  
  8. <sectionGroup name="customSectionGroup" type="Tonnie.Configuration.Library.CustomSectionGroup, Tonnie.Configuration.Library, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" >
  9. <section name="customSectionA" type="Tonnie.Configuration.Library.CustomSectionWithChildElement, Tonnie.Configuration.Library, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
  10. </sectionGroup>
  11. </configSections>
  12. <MySectionGroup>
  13. <MyFirstSection>
  14. <add key="First" value="First Section"/>
  15. </MyFirstSection>
  16. <MySecondSection>
  17. <add key="Second" value="Second Section"/>
  18. </MySecondSection>
  19. </MySectionGroup>
  20. <customSectionGroup>
  21. <customSectionA>
  22. <childSectionA childId="" childValue="ChildA" />
  23. <childSectionB childId="" childValue="ChildB" />
  24. </customSectionA>
  25. </customSectionGroup>
  26. </configuration>
  1. 3 高级使用
  1. 到目前为止可能大家对app.config有了一定的认识了,我们自己可以不断的去扩展.NET Framework提供给我们的类,从SectionGroup,Section,ElementCollectionElement 从上自下的一级一级的组装成符合工程化项目配置文件需要的形式。当遇到可能配置元素的类型属性差不多时,可以抽象出一个base类来。比如可以抽象出Section这一层面的base类,或者ElementCollectionElement这一层的抽象类(可以是抽象的泛型类)来。同时增加泛型来更好的支持扩展。

使用.NET Framework的配置文件app.config的更多相关文章

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

    转自https://www.cnblogs.com/tonnie/archive/2010/12/17/appconfig.html 在一般的项目中,为了使你的代码更加灵活,更方便调整,减少不必要的h ...

  2. 配置文件App.config的使用以及Readonly与Const的对比

    以前我们学习的时候都把连接数据库的连接字符串写在一个类中,因为我们的数据库都在自己电脑上.如果更换数据库地址,需要更改这个类,然后重新编译才可以连接到数据库.现在我们需要将连接字符串当道一个文件中,然 ...

  3. C#的配置文件App.config使用总结 - 转

    http://blog.csdn.net/celte/article/details/9749389 首先,先说明,我使用的app.config 配置文件的格式如下: <?xml version ...

  4. winform程序读取和改写配置文件App.config元素的值

    winform程序读取和改写配置文件App.config元素的值 2016-05-16 17:49 by newbirth, 2412 阅读, 0 评论, 收藏, 编辑 1 2 3 4 5 6 7 & ...

  5. C#的配置文件App.config使用总结

    应用程序配置文件是标准的 XML 文件,XML 标记和属性是区分大小写的.它是可以按需要更改的,开发人员可以使用配置文件来更改设置,而不必重编译应用程序.配置文件的根节点是configuration. ...

  6. 配置文件——App.config文件读取和修改

    作为普通的xml文件读取的话,首先就要知道怎么寻找文件的路径.我们知道一般配置文件就在跟可执行exe文件在同一目录下,且仅仅在名称后面添加了一个.config 因此,可以用Application.Ex ...

  7. C#中怎样获取默认配置文件App.config中配置的键值对内容

    场景 在新建一个程序后,项目中会有一个默认配置文件App.config 一般会将一些配置文件信息,比如连接数据库的字符串等信息存在此配置文件中. 怎样在代码中获取自己配置的键值对信息. 注: 博客主页 ...

  8. C#----操作应用程序配置文件App.config

    对配置文件的一些疑问: 在应用程序的目录下,有两处值得注意的地方,一个是应用程序根目录下的App.config文件,和bin\debug\name.exe.config 或者 bin\Release\ ...

  9. 通过读取配置文件App.config来获取数据库连接字符串

    有两种方式://通过读取配置文件来获取连接字符串 第一种方式: App.config 文件的格式: <?xml version="1.0" encoding="ut ...

随机推荐

  1. NET-SNMP开发——日志输出

    NET-SNMP开发——日志输出 net-snmp的日志输出功能是很强大的,与日志输出相关函数声明在net-snmp-5.7.3\include\net-snmp\library\snmp_loggi ...

  2. leetcode:32 最长有效括号

     题目: 给一个包含了'(' 和 ')'的字符串,求出其中最长有效括号的长度. 做题情况:自己做出来,但做了较长的时间. 思路:可以算得穷举法的时间复杂度为O(n^3).虽然这题求的是最长的长度,但是 ...

  3. Activity中UI框架基本概念

    Activity中UI框架基本概念 Activity 是应用程序的基本组成部分,提供了可视的界面,UI容器, 与用户进行交互: 具体Acitivity是怎么样显示这些事视图元素以及响应事件交互的. 一 ...

  4. AFNetworking 2.5.0版本的使用

    http://www.mamicode.com/info-detail-477899.html AFNetworking 2.5.0版本的使用 http://afnetworking.com/ htt ...

  5. JQuery 遍历 - prev() 方法

    http://www.w3school.com.cn/jquery/traversing_prev.asp http://www.w3school.com.cn/jquery/jquery_ref_t ...

  6. 《oracle每天一练》Oracle之物化视图

    相关帖子思考和跟踪 本文转自Ronger 物化视图是一种特殊的物理表,“物化”(Materialized)视图是相对普通视图而言的.普通视图是虚拟表,应用的局限性大,任何对视图的查询,Oracle都实 ...

  7. poj 1847( floyd && spfa )

    http://poj.org/problem?id=1847 一个水题,用来熟悉熟悉spfa和floyd的. 题意:有m条的铁路,要从x,到y, 之后分别就是条铁路与其他铁路的交点.第一个输入的为有n ...

  8. Unity3d 扩展自定义类Inspector

    public class MyClass : MonoBehaviour { public int A; // Use this for initialization void Start () { ...

  9. redis与memcache区别总结

    2015年9月2日 14:04:19 总会被问到两者的区别, 在这里总结下: redis 有内置的多种数据结构, list(可用于实现小型队列), hash, set, zset...; memcac ...

  10. code vs1436 孪生素数 2(数论+素数的判定)

    1436 孪生素数 2  时间限制: 2 s  空间限制: 1000 KB  题目等级 : 白银 Silver 题解  查看运行结果     题目描述 Description 如m=100,n=6 则 ...