写在前面的话:本来想直接写Enterprise Library 4.1的核心三大组件之Configuration的,但是想了想,这部分是从System.Configuration扩展来的,所以先大概介绍一下.Net 2.0的System.Configuration的自定义Configuration Section,然后在下一篇文章中再和和大家详细探讨一下Enlib的Common.Configuration。如果大家对Enterprise Library和Unity的创建感兴趣可以先看一下我的另一篇文章:ObjectBuilder2.0 的学习
背景介绍
多数的.Net应用程序都有自己的一个或几个配置文件,这些配置文件保存了诸如数据库连接字符串,邮件服务配置,等等配置信息。这些配置信息本来可以硬编码在源代码中,但是通常会把它们放到配置文件中如web.config, app.config等。这样儿的好处是,在配置文件中修改这些值比编写代码要容易,而且应用程序更易于重新编译,重新部署。
在.Net 2.0以上版本,微软在配置文件中提供了预定义的 custom configuration sections和一些新的configuration的API,使开发人员更加容易的操作配置文件信息。比如:应用服务器,可以连接到几个数据库,默认从几个数据库连接选择一个连接,在配置文件中可以这样描述:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="connectionStringSection" type="CustomConfigurationSection.ConnectionStringSection, CustomConfigurationSection" />
</configSections>
<connectionStringSection selectConnectionString="Oracle">
<connectionStrings>
<add name="SqlServer" value="SqlServerConnectionString........."/>
<add name="Oracle" value="OracleConnectionString......."/>
<add name="DB2" value="DB2ConnectionString......."/>
</connectionStrings>
</connectionStringSection>
</configuration>
(对于数据库连接其实配置文件已经提供了默认的元素设置,这里只是为了给大家举个例子如何操作自定义的configuration section,大家不要深究。)
创建配置类
要想操作自定义的configuration section,需要应用.Net 2.0的System.Configuration类库,首先需要创建一个从ConfigurationSection class继承的类,这个类用来描述配置文件中的自定义configuration section的根元素。通过ConfigurationProperty attribue标示自定义的ConfigurationSection的属性,可以使应用程序取得它的配置信息。
看看上面的配置文件,需要定义两个属性,selectConnectionString 和 connectionStrings。创建一个带有上面两个属性的自定义的Configuration Section 类,代码如下:
public class ConnectionStringSection : ConfigurationSection
{
[ConfigurationProperty("selectConnectionString", DefaultValue = "SqlServer", IsRequired = false)]
public string SelectConnectionString
{
get
{
return this["selectConnectionString"] as string;
}
}
[ConfigurationProperty("connectionStrings", IsRequired = true)]
public ConnectionStringCollection ConnectionStrings
{
get
{
return this["connectionStrings"] as ConnectionStringCollection;
}
}
}
着重看一下加粗的代码部分,首先注意ConnectionStringSection类一定要继承自ConfigurationSection类。其次,注意这个类的两个属性SelectConnectionString和ConnectionStrings。它们都需要用ConfigurationProperty attribute标记一下,用来和配置文件的属性相互对应。这个attribute有以下几个参数:
Name – 表示配置文件中对应的属性名字
DefaultValue – 表示这个属性的默认值
IsRequired – 表示这个属性在配置文件中是否是必须的。
最后,看一下this[“XmlAttributeName”],通过它来访问配置文件信息。
配置文件如何配置Custom Configuration Section
看一下下面的配置文件信息,如果要用自定义的Configuration Section,需要按下面的方式定义section元素:
<configSections>
<section name="connectionStringSection" type="CustomConfigurationSection.ConnectionStringSection, CustomConfigurationSection" />
</configSections>
其中type的值表示自定义Configuration Section完整的类的名字,格式为”Namespace.ClassName, AssemblyName”。然后再把此section加入到configSections标签中即可。
获取基于集合的配置信息
看看前面的配置文件信息和自定义的Configuration Section类,发现定义的两个属性,是两种类型,第一个SelectConnectionString属性在配置文件中是以connectionStringSection元素的属性形式来描述的,表示要选择哪一个数据库连接。而第二个属性ConnectionStrings是一个集合信息,表示一组数据库连接字符串,已经有了在配置文件中的定义如下:
<connectionStringSection selectConnectionString="Oracle">
<connectionStrings>
<add name="SqlServer" value="SqlServerConnectionString........."/>
<add name="Oracle" value="OracleConnectionString......."/>
<add name="DB2" value="DB2ConnectionString......."/>
</connectionStrings>
</connectionStringSection>
那么在代码中怎么实现?用.Net 2.0 的Configuration API 需要实现两个类,一个用来描述集合中的每个实例,另一个用来描述整个集合。
通过配置文件可知,描述数据库连接的集合它的实例是每个连接元素,包括连接串名字和连接串值两个属性值。根据.Net 2.0 Configuration API,这个描述连接字符串实例的类必须继承自ConfigurationElement类,和上面自定义Configuration Section一样,属性需要用ConfigurationProperty attribute标记一下,代码如下:
public class ConnectionString : ConfigurationElement
{
[ConfigurationProperty("name", IsRequired = true)]
public string Name
{
get { return this["name"] as string; }
}
[ConfigurationProperty("value", IsRequired = true)]
public string Value
{
get { return this["value"] as string; }
}
}
还需要一个类来描述 ConnectionString 类的对象集合,此类必须继承自ConfigurationElementCollection 类,并且需要至少重写CreateNewElement和GetElementKey两个方法。CreateNewElement方法负责给集合创建新的对象实例。GetElementKey方法负责取得集合中的实例。同时可以根据集合的特性,编写自己的索引器等方法,代码如下:
public class ConnectionStringCollection : ConfigurationElementCollection
{
public ConnectionString this[int index]
{
get
{
return base.BaseGet(index) as ConnectionString;
}
set
{
if (base.BaseGet(index) != null)
base.BaseRemoveAt(index);
this.BaseAdd(index, value);
}
}
protected override ConfigurationElement CreateNewElement()
{
return new ConnectionString();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((ConnectionString)element).Name;
}
public ConnectionString Get(string name)
{
return BaseGet(name) as ConnectionString;
}
}
在代码中使用配置信息
我们可以用ConfigurationManager类对前面定义好的配置文件类来进行需要的操作,通过ConfigurationManager.GetSection(string sectionName)取得系统默认配置文件的自定义的Configuration Section对象。
还可以通过 如下代码取得非缺省配置文件信息:
ExeConfigurationFileMap file = new ExeConfigurationFileMap();
file.ExeConfigFilename = "Test.config";
Configuration config = ConfigurationManager.OpenMappedExeConfiguration(file, ConfigurationUserLevel.None);
在通过取得的configuration对象或者Section对象来进行操作。
附件:文中的demo http://files.cnblogs.com/zranran/CustomConfigurationSection.rar