标签:选择 strong .config 获取 设计 none data 变化 cond
转自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
标签:选择 strong .config 获取 设计 none data 变化 cond
原文地址:http://www.cnblogs.com/zhangwei99com/p/7811328.html