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#方面有什么一技之长,都可私聊我,入群和我们共同玩耍,呵呵,我说不出肉麻的话,你们懂得哈!