.Net 自定义应用程序配置二(参照张子阳博客)

      除了实现IConfigurationSectionHandler接口来自定义结点处理程序,还可以通过继承ConfigurationSection基类的方式来完成,我们还以上面的例子来做说明。一般来说我们想要存储的数据可以用两种方式来存储:一种是存储到结点的属性中,一种是存储在结点的文本(InnerText)中。比如:

<node>这里是要存储的值</node>
<!-- 或者是下面这样,两种的效果是一样的  -->
<node text="这里是要存储的值" />

      因为一个结点可以有很多的属性,但只有一个InnerText,而在程序又要将这两种形式区别处理显然太麻烦了,所以Microsoft干脆就只使用属性存储而不使用InnerText,大家可以看一下machine.config中的配置,可曾见到过一个以InnerText来存储配置信息的?在ConfigurationSection中,也没有提供对InnerText的处理,所以对于上面的例子,我们首先要进行重新格式化,仅使用属性来存储我们的配置值。

      除此以外,我们还要将结点分组,对于入口结点,也就是mailServerGroup而言,这个结点组相当于它的一个属性(就好像provider一样),因为结点组包含多个结点,所以映射到面向对象的代码中,自然就成了一个集合类。所以我们需要按照这些概念将web.config中的mailServerGroup改写成下面这样:

代码
<mailServerGroup2 provider="www.edong.com">
<mailServers>
<mailServer
client
="forum.tracefact.net"
address
="mail1.tracefact.net"
userName
="jimmyzhang"
password
="123456" />
<mailServer
client
="blog.tracefact.net"
address
="mail2.tracefact.net"
userName
="webmaster"
password
="456789" />
</mailServers>
</mailServerGroup2>

注意,我们将mailServerGroup改成了mailServerGroup2,以免和上一节的冲突。现在我们在CustomConfig项目中添加一个文件 MailServerSection.cs,然后添加如下代码:

// MailServerSection 为入口

 

代码
public class MailServerSection : ConfigurationSection {

[ConfigurationProperty(
"provider", IsKey = true)]
public string Provider {
get { return this["provider"] as string; }
}

[ConfigurationProperty(
"mailServers", IsDefaultCollection = false)]
public MailServerCollection MailServers {
get {
return (MailServerCollection)this["mailServers"];
}
set {
this["mailServers"] = value;
}
}
}

 

// MailServer 结点和集合类

 

代码
public sealed class MailServerElement : ConfigurationElement {

[ConfigurationProperty(
"client", IsKey = true, IsRequired = true)]
public string Client {
get { return this["client"] as string; }
set { this["client"] = value; }
}

[ConfigurationProperty(
"address")]
public string Address {
get { return this["address"] as string; }
set { this["client"] = value; }
}

[ConfigurationProperty(
"userName")]
public string UserName {
get { return this["userName"] as string; }
set { this["client"] = value; }
}

[ConfigurationProperty(
"password")]
public string Password {
get { return this["password"] as string; }
set { this["client"] = value; }
}
}

// MailServer 集合类
public sealed class MailServerCollection : ConfigurationElementCollection {

public override ConfigurationElementCollectionType CollectionType {
get { return ConfigurationElementCollectionType.BasicMap; }
}

protected override ConfigurationElement CreateNewElement() {
return new MailServerElement();
}

protected override Object GetElementKey(ConfigurationElement element) {
return ((MailServerElement)element).Client;
}

protected override string ElementName {
get { return "mailServer"; }
}

public new int Count {
get { return base.Count; }
}


public MailServerElement this[int index] {
get {
return (MailServerElement)BaseGet(index);
}
set {
if (BaseGet(index) != null) {
BaseRemoveAt(index);
}
BaseAdd(index, value);
}
}

new public MailServerElement this[string Name] {
get {
return (MailServerElement)BaseGet(Name);
}
}

public int IndexOf(MailServerElement element) {
return BaseIndexOf(element);
}

public void Add(MailServerElement element) {
BaseAdd(element);
}

public void Remove(MailServerElement element) {
if (BaseIndexOf(element) >= 0)
BaseRemove(element.Client);
}

public void RemoveAt(int index) {
BaseRemoveAt(index);
}

public void Remove(string client) {
BaseRemove(client);
}

public void Clear() {
BaseClear();
}
}

     这段代码由三部分组成,一部分是MailServerSection类,很明显它是配置结点的入口,它包含两个属性,一个是String类型的provider属性,它映射mailServerGroup结点的provider属性;一个是MailServerCollection类型的MailServers属性,这个属性映射我们新添加的mailServers结点,mailServers结点下还包含了若干个mailServer结点。从它的名称也可以看出来,它是一个集合类。

      MailServerElement类用于映射mailServer结点的属性,这里是我们实际存储数据的地方。MailServerCollection类用于映射mailServers结点,可以看出它是一个集合类,另外还包含了很多对于结点进行操作的方法,大部分的能力都继承自ConfigurationElementCollection基类。

值得注意的是,之所以可以使用这种方式实现,使用了大量的特性标记。当你看到特性标记的时候,你应该就想到必须有地方使用反射来读取特性的值,不然特性毫无意义。只是这部分的内容属于.Net Framework的底层,无需我们操心。

原文链接:http://www.tracefact.net/CLR-and-Framework/Custom-Application-Configuration.aspx

posted @ 2010-12-30 15:05  雁北飞  阅读(181)  评论(0编辑  收藏  举报