在Web.config或App.config中的添加自定义配置

转自:http://www.cnblogs.com/yukaizhao/archive/2011/12/02/net-web-config-costom-config-implement.html

.Net中的System.Configuration命名空间为我们在web.config或者app.config中自定义配置提供了完美的支持。最近看到一些项目中还在自定义xml文件做程序的配置,所以忍不住写一篇用系统自定义配置的随笔了。

如果你已经对自定义配置了如指掌,请忽略这篇文章。

言归正传,我们先来看一个最简单的自定义配置

?
<? xml version = "1.0" encoding = "utf-8" ?>
< configuration >
  < configSections >
    < section name = "simple" type = "ConfigExample.Configuration.SimpleSection,ConfigExample" />
  </ configSections >
  < simple maxValue = "20" minValue = "1" ></ simple >
</ configuration >

在配置文件中使用自定义配置,需要在configSections中添加一个section元素,并制定此section元素对应的类型和名字。然后再在configuration根节点下面添加此自定义配置,如上例中的simple节点。simple节点只有两个整形数的属性maxValue和minValue。

要在程序中使用自定义配置我们还需要实现存取这个配置块的类型,一般需要做如下三件事:
1. 定义类型从System.Configuration.ConfigurationSection继承
2. 定义配置类的属性,这些属性需要用ConfigurationProperty特性修饰,并制定属性在配置节中的名称和其他一些限制信息
3. 通过基类的string索引器实现属性的get ,set

非常简单和自然,如下是上面配置类的实现:

?
public class SimpleSection:System.Configuration.ConfigurationSection
{
    [ConfigurationProperty( "maxValue" ,IsRequired= false ,DefaultValue=Int32.MaxValue)]
    public int MaxValue
    {
        get
        {
            return  ( int ) base [ "maxValue" ];
        }
        set
        {
            base [ "maxValue" ] = value;
        }
    }
    [ConfigurationProperty( "minValue" ,IsRequired= false ,DefaultValue=1)]
    public int MinValue
    {
        get { return ( int ) base [ "minValue" ];}
        set { base [ "minValue" ] = value; }
    }
    [ConfigurationProperty( "enabled" ,IsRequired= false ,DefaultValue= true )]
    public bool Enable
    {
        get
        {
            return ( bool ) base [ "enabled" ];
        }
        set
        {
            base [ "enabled" ] = value;
        }
    }
}

这样子一个简单的配置类就完成了,怎么在程序中使用这个配置呢?需要使用ConfigurationManager类(要引用System.configuration.dll这个dll只有在.Net2.0之后的版本中才有)的GetSection方法获得配置就可以了。如下代码:

?
SimpleSection simple = ConfigurationManager.GetSection( "simple" ) as SimpleSection;
Console.WriteLine( "simple minValue={0} maxValue = {1}" ,simple.MinValue,simple.MaxValue);

这个配置类太过简陋了,可能有时候我们还需要更复杂的构造,比如在配置类中使用类表示一组数据,下面我们看一个稍微复杂一点的自定义配置

?
<? xml version = "1.0" encoding = "utf-8" ?>
< configuration >
  < configSections >
    < section name = "complex" type = "ConfigExample.Configuration.ComplexSection,ConfigExample" />
  </ configSections >
  < complex height = "190" >
    < child firstName = "James" lastName = "Bond" />
  </ complex >
</ configuration >

这个配置的名字是complex,他有一个属性height,他的节点内还有一个child元素这个元素有两个属性firstName和lastName;对于这个内嵌的节点该如何实现呢?首先我们需要定义一个类,要从ConfigurationElement类继承,然后再用和SimpleSection类似的方法定义一些用ConfigurationProperty特性修饰的属性就可以了,当然属性值的get,set也要使用基类的索引器。如下实现:

?
public class ComplexSection : ConfigurationSection
{
    [ConfigurationProperty( "height" , IsRequired = true )]
    public int Height
    {
        get
        {
            return ( int ) base [ "height" ];
        }
        set
        {
            base [ "height" ] = value;
        }
    }
    [ConfigurationProperty( "child" , IsDefaultCollection = false )]
    public ChildSection Child
    {
        get
        {
            return (ChildSection) base [ "child" ];
        }
        set
        {
            base [ "child" ] = value;
        }
    }
}
public class ChildSection : ConfigurationElement
{
    [ConfigurationProperty( "firstName" , IsRequired = true , IsKey = true )]
    public string FirstName
    {
        get
        {
            return ( string ) base [ "firstName" ];
        }
        set
        {
            base [ "firstName" ] = value;
        }
    }
    [ConfigurationProperty( "lastName" , IsRequired = true )]
    public string LastName
    {
        get
        {
            return ( string ) base [ "lastName" ];
        }
        set
        {
            base [ "lastName" ] = value;
        }
    }
}

还有稍微再复杂一点的情况,我们可能要在配置中配置一组相同类型的节点,也就是一组节点的集合。如下面的配置:

?
<? xml version = "1.0" encoding = "utf-8" ?>
< configuration >
  < configSections >
    < section name = "complex" type = "ConfigExample.Configuration.ComplexSection,ConfigExample" />
  </ configSections >
  < complex height = "190" >
    < child firstName = "James" lastName = "Bond" />
    < children >
      < add firstName = "Zhao" lastName = "yukai" />
      < add firstName = "Lee" lastName = "yukai" />
      < remove firstName = "Zhao" />
    </ children >
  </ complex >
</ configuration >

请看children节点,它就是一个集合类,在它里面定义了一组add元素,也可以有remove节点把已经添进去的配置去掉。

要使用自定义节点集合需要从ConfigurationElementCollection类继承一个自定义类,然后要实现此类GetElementKey(ConfigurationElement element)和ConfigurationElement CreateNewElement()两个方法;为了方便的访问子节点可以在这个类里面定义只读的索引器。请看下面的实现

?
public class Children : ConfigurationElementCollection
{
    protected override object GetElementKey(ConfigurationElement element)
    {
        return ((ChildSection)element).FirstName;
    }
    protected override ConfigurationElement CreateNewElement()
    {
        return new ChildSection();
    }
    public ChildSection this [ int i]
    {
        get
        {
            return (ChildSection) base .BaseGet(i);
        }
    }
    public ChildSection this [ string key]
    {
        get
        {
            return (ChildSection) base .BaseGet(key);
        }
    }
}

当然要使用此集合类我们必须在Complex类中添加一个此集合类的属性,并要指定集合类的元素类型等属性,如下:

?
[ConfigurationProperty( "children" , IsDefaultCollection = false )]
    [ConfigurationCollection( typeof (ChildSection), CollectionType = ConfigurationElementCollectionType.AddRemoveClearMap, RemoveItemName = "remove" )]
    public Children Children
    {
        get
        {
            return (Children) base [ "children" ];
        }
        set
        {
            base [ "children" ] = value;
        }
}

我们会经常用到类似appSettings配置节的键值对的构造,这时候我们就不必再自己实现了,我们可以直接使用现有的System.Configuration.NameValueConfigurationCollection类来定义一个自定义的键值对。可以在Complex类中定义如下属性

?
[ConfigurationProperty( "NVs" , IsDefaultCollection = false )]
    public System.Configuration.NameValueConfigurationCollection NVs
    {
        get
        {
            return (NameValueConfigurationCollection) base [ "NVs" ];
        }
        set
        {
            base [ "NVs" ] = value;
        }
}

然后在配置文件的complex节中添加键值对配置

?
< NVs >
    < add name = "abc" value = "123" />
    < add name = "abcd" value = "12d3" />
</ NVs >

到这儿已经基本上可以满足所有的配置需求了。不过还有一点更大但是不复杂的概念,就是sectionGroup。我们可以自定义SectionGroup,然后在sectionGroup中配置多个section;分组对于大的应用程序是很有意义的。

如下配置,配置了一个包含simple和一个complex两个section的sectionGroup

?
<? xml version = "1.0" encoding = "utf-8" ?>
< configuration >
  < configSections >
    < sectionGroup type = "ConfigExample.Configuration.SampleSectionGroup,ConfigExample" name = "sampleGroup" >
      < section type = "ConfigExample.Configuration.SimpleSection,ConfigExample" allowDefinition = "Everywhere" name = "simple" />
      < section type = "ConfigExample.Configuration.ComplexSection,ConfigExample" allowDefinition = "Everywhere" name = "complex" />
    </ sectionGroup >
  </ configSections >
  < sampleGroup >
    < simple maxValue = "20" minValue = "1" >
    </ simple >
    < complex height = "190" >
      < child firstName = "James" lastName = "Bond" />
      < children >
        < add firstName = "Zhao" lastName = "yukai" />
        < add firstName = "Lee" lastName = "yukai" />
        < remove firstName = "Zhao" />
      </ children >
  < NVs >
    < add name = "abc" value = "123" />
    < add name = "abcd" value = "12d3" />
  </ NVs >
    </ complex >
  </ sampleGroup >
</ configuration >

为了方便的存取sectionGroup中的section我们可以实现一个继承自System.Configuration.ConfigurationSectionGroup类的自定义类。实现很简单,就是通过基类的Sections[“sectionName”]索引器返回Section。如下:

?
public class SampleSectionGroup : System.Configuration.ConfigurationSectionGroup
{
    public SimpleSection Simple
    {
        get
        {
            return (SimpleSection) base .Sections[ "simple" ];
        }
    }
    public ComplexSection Complex
    {
        get
        {
            return (ComplexSection) base .Sections[ "complex" ];
        }
    }
}

需要注意的是SectionGroup不能使用ConfigurationManager.GetSection(string)方法来获得,要获得sectionGroup必须通过Configuration类的SectionGroups[string]索引器获得,如下示例代码:

?
SampleSectionGroup sample = (SampleSectionGroup)ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None).SectionGroups[ "sampleGroup" ];

总结:

.Net framework给我们提供了一套很方便的配置库,我们只需要继承对应的类简单的配置一下就可以方便的使用在web.config或者app.config中配置的自定义节点了。

自定义配置文件节源码

我的微博地址是: http://weibo.com/yukaizhao 我会把一些技术心得碎片写到微博中,欢迎关注。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值