AaronYang的C#私房菜[一][App.Config文件外传]

今天 是第一次有这个想法,想和大家分享自己的编程经验。我工作年龄那么短,能有资格写好吗?我只能说我尽力吧。这个系列讲的一些“哇!原来还可以这样写”的知识。很多技巧也是自己折腾出来的。

我们C#实验室,一直坚持没事瞎折腾,一帮大老爷们,70后,80后,90后组成的一个50人群体,曾经我许诺过群友,6月1日后就好好搞,其实里面技术比我高的人数不胜数。很感激他们,我们人少,但是团结,有负责感情,职业方面的10年经验的jack兄弟,有懂算法丰富经验的Yamat兄弟(二哥),有WPF xaml方面的蓝言 蓝言经常热心帮助朋友解决问题,经常帮助基友远程操作,比如蓝言教yamat 面向对象编程,yamat也帮蓝言和其他朋友,我们互相帮助学习提升友谊,还有卖萌搞笑技术也很好的Sandy(我们喊他三弟)还有很多好朋友,感谢他们给我帮助。

版权声明:http://www.cnblogs.com/AaronYang/archive/2013/06/07/3123157.html  本文禁止任何转载,保留AaronYang的知识产权。

 

1 . App.config文件中的细节(DEMO下载

新建控制台程序,名字叫 TestConfig,然后新建文件夹 Config,修改目标框架,引用System.Configuration类库

平时大家肯定都是把所有的配置都放到了app.config中去了,各别第三方的类库使用的时候可能也要配置,一大堆冗余的配置一定不好管理。其实config中的配置是可以分离出去的,现在我们把app.config文件中的配置 分离到多个config文件中去,这些文件我们放到Config文件夹去,方便以后维护

1.1  configSource

在Config文件中新建DBConnection.config文件

添加配置

<?xml version="1.0" encoding="utf-8" ?>
<connectionStrings>
  <add name="TestDBConnectionString" connectionString="data source=.;initial catalog=TestDB;user id=sa;password=sa"/>
</connectionStrings>

右键DBConnection.config文件设置一下生成属性:

选择 如果教新则复制,这样生成后 Debug或者Release文件夹下才会有这个文件,我们才能读取配置

打开app.config 添加配置如下:

<?xml version="1.0"?>
<configuration>
  <connectionStrings configSource="Config\DBConnection.config"/>
 
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
  </startup>
</configuration>

 

重点(自己看图解释):

 

Config\DBConnection.config中的根节点的名字要跟 app.config中 configSource的签名的节点名字一模一样,才能插入Config\DBConnection.config那个文件里的其他配置。以后修改我们只要修改Config\DBConnection.config中的就行了,如果你有多个需要配置,多建立几个config文件,大架构的config一般都分离,方便维护

 

测试效果(Program.cs文件编写代码如下):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
 
namespace TestConfig
{
    class Program
    {
        static void Main(string[] args)
        {
            //Demo1
            string connectionString = ConfigurationManager.ConnectionStrings["TestDBConnectionString"].ToString();
            Console.WriteLine(connectionString);
 
            Console.ReadLine();
        }
    }
}

效果如下

成功的!

 

 

 

2 .  App.config中的自定义配置

2.1 基本样子,自定义配置可分为:自定义配置节和自定义配置节组。

<configuration>
    <configSections>     //配置节声明区域,包含配置节和命名空间声明
        <section>               //配置节声明
            <sectionGroup/>        //定义配置节组
        </section>        //配置节组中的配置节声明
    </configSections>
    <appSettings/> //预定义配置节
    <Custom element for configuration section>   //配置节设置区域
</configuration>

2.2 开始练习DEMO

(零)section有2块,name和type,type如下

(一) SingleTagSectionHandler

①添加如下配置

注意 section的名字为InnerNetTest,接下来我们就可以添加一个InnerNetTest名称的节点了,添加自定义的属性,方便程序中使用

Program.cs开始文件测试

其他代码:

     IDictionary demo2 = ConfigurationManager.GetSection("InnerNetTest") as IDictionary;
            Console.WriteLine(string.Format(@"是否启用{0}  ip地址", demo2["enabled"], demo2["ip"]));

运行发现会错误! 因为app.config中的configSections要放在顶部

我们调整配置的顺序

<?xml version="1.0"?>
<configuration>
  <configSections>
    <section name="InnerNetTest" type="System.Configuration.SingleTagSectionHandler"/>
  </configSections>
  <InnerNetTest enabled="true" ip="192.168.10.110:2000"/>
  <connectionStrings configSource="Config\DBConnection.config"/>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
  </startup>
</configuration>

效果:

 

成功了!

 

 

(二) SingleTagSectionHandler

我们添加第二个Section,添加key,value形式的值

<?xml version="1.0"?>
<configuration>
  <configSections>
    <section name="InnerNetTest" type="System.Configuration.SingleTagSectionHandler"/>
    <section name="InnerNetCollection" type="System.Configuration.DictionarySectionHandler"/>
  </configSections>
  <InnerNetTest enabled="true" ip="192.168.10.110:2000"/>
  <InnerNetCollection>
    <add key="innerip" value="192.168.10.110:2000"/>
    <add key="pip" value="192.168.10.120"/>
    <add key="realip" value="192.168.10.150"/>
  </InnerNetCollection>
  <connectionStrings configSource="Config\DBConnection.config"/>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
  </startup>
</configuration>

Program.cs

     //Demo3
            IDictionary demo3 = ConfigurationManager.GetSection("InnerNetCollection") as IDictionary;
            foreach (DictionaryEntry e in demo3)
            {
                Console.WriteLine(string.Format("键{0}  值{1}", e.Key, e.Value));
            }

效果:

 

成功了!

 

 

(三) SingleTagSectionHandler

继续在configSections添加<section>,最终如下

<?xml version="1.0"?>
<configuration>
  <configSections>
    <section name="InnerNetTest" type="System.Configuration.SingleTagSectionHandler"/>
    <section name="InnerNetCollection" type="System.Configuration.DictionarySectionHandler"/>
    <section name="InnerNetCollection2" type="System.Configuration.NameValueSectionHandler"/>
  </configSections>
  <InnerNetTest enabled="true" ip="192.168.10.110:2000"/>
  <InnerNetCollection>
    <add key="innerip" value="192.168.10.110:2000"/>
    <add key="pip" value="192.168.10.120"/>
    <add key="realip" value="192.168.10.150"/>
  </InnerNetCollection>
  <InnerNetCollection2>
    <add key="innerip" value="hello"/>
    <add key="innerip" value="world"/>
    <add key="pip" value="AaronYang"/>
    <add key="realip" value="cnblogs"/>
  </InnerNetCollection2>
  <connectionStrings configSource="Config\DBConnection.config"/>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
  </startup>
</configuration>

Program.cs

   //Demo4
            //NameValueCollection demo4 = (NameValueCollection)ConfigurationManager.GetSection("InnerNetCollection2");  //这个方法已经过时,我们可以这样写
            NameValueCollection demo4 =ConfigurationManager.GetSection("InnerNetCollection2") as NameValueCollection;  
            Console.WriteLine(demo4.AllKeys[0].ToString()+"   "+demo4["innerip"]);

效果图:

 

其实按我的理想应该是 Hello,world,但是结果不是,因为NameValueCollection集合是一个键对应多个string,如果键一样,合并结果Hello,world,但是不是,求大神这样的结果对吗?

 

 

 (四) sectionGroup

我们添加<sectionGroup>然后取一个名字,然后在里面写<section>取个名字,然后在下面添加具体细节

<group的名字><group里面的section的名字><add key=... value=...>...<add key=... value=...></group里面的section的名字></group的名字>

<?xml version="1.0"?>
<configuration>
  <configSections>
    <section name="InnerNetTest" type="System.Configuration.SingleTagSectionHandler"/>
    <section name="InnerNetCollection" type="System.Configuration.DictionarySectionHandler"/>
    <section name="InnerNetCollection2" type="System.Configuration.NameValueSectionHandler"/>
    <sectionGroup name="Students">
      <section name="Student" type="System.Configuration.DictionarySectionHandler"/>
    </sectionGroup>
  </configSections>
  <InnerNetTest enabled="true" ip="192.168.10.110:2000"/>
  <InnerNetCollection>
    <add key="innerip" value="192.168.10.110:2000"/>
    <add key="pip" value="192.168.10.120"/>
    <add key="realip" value="192.168.10.150"/>
  </InnerNetCollection>
  <InnerNetCollection2>
    <add key="innerip" value="hello"/>
    <add key="innerip" value="world"/>
    <add key="pip" value="AaronYang"/>
    <add key="realip" value="cnblogs"/>
  </InnerNetCollection2>
  <Students>
    <Student>
      <add key="1000" value="王磊"/>
      <add key="1001" value="王类"/>
      <add key="1002" value="王雷"/>
    </Student>
  </Students>
  <connectionStrings configSource="Config\DBConnection.config"/>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
  </startup>
</configuration>

Program.cs调用

    //Demo5
            IDictionary demo5 = ConfigurationManager.GetSection(@"Students/Student") as IDictionary;
            foreach (DictionaryEntry e in demo5)
            {
                Console.WriteLine(string.Format("键:{0}  值:{1}", e.Key, e.Value));
            }

效果图:

成功了!

 

(五) IConfigurationSectionHandler 

     新建一个类InnerConfigTest,实现 IConfigurationSectionHandler

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using System.Collections;
using System.Xml;

namespace TestConfig
{
    public class InnerConfigTest : IConfigurationSectionHandler
    {
        private string enabled;
        public string Enabled
        {
            get { return enabled; }
            set { enabled = value; }
        }

        private string ip;
        public string IP
        {
            get { return ip; }
            set { ip = value; }
        }

        public object Create(object parent, object configContext, System.Xml.XmlNode section)
        {
            Hashtable hashtable = new Hashtable();
            foreach (XmlAttribute attribute in section.Attributes)
            {
                hashtable[attribute.Name] = attribute.Value;
            }
            return hashtable;
        }
      
    }
}

我们接下来可以在app.config中添加配置

configSections中添加

    <section name="InnerConfigTest" type="System.Configuration.SingleTagSectionHandler"/>

然后对应的细节

 <InnerConfigTest enabled="true" ip="192.168.10.110:8888"/>

Program.cs

     InnerConfigTest us = new InnerConfigTest();
            Hashtable ht = ConfigurationManager.GetSection(@"InnerConfigTest") as Hashtable;
            us.Enabled = (string)ht["enabled"];
            us.IP = (string)ht["ip"];
            Console.WriteLine(us.Enabled+"   "+us.IP);

因为InnerConfigTest的Create方法返回的其实本质是Hashtable的object,所以用Hashtable接受,如果返回一个List也行,就看你怎么在Create方法里面怎么写了,里面其实是一个XML的操作

这里我就暂时讲到这里了

效果图:

成功了!

 

 

一切我暂时先将这么多了,总结一下

①你可以知道怎样让app.config更加简洁,通过分离部分的配置,通过configSource引入

②具体的某些自定义字典在XML配置的使用

③如何使用IConfigurationSectionHandler ,让代码显得更高级

④你学到东西了!呵呵

⑤谢谢 C#实验室 群里面的好朋友对我的支持,C#实验室人已经满50人了,如果你的技术确实不错,或者你在C#方面有什么一技之长,都可私聊我,入群和我们共同玩耍,呵呵,我说不出肉麻的话,你们懂得哈!

posted @ 2013-06-07 16:43  AYUI框架  阅读(1949)  评论(16编辑  收藏  举报