目录
从配置信息可以看出,我们需要实现一个类CustomSingleSection.SingleSectionHandler,该类有2个属性,一个属性类型为string,名称为myAttrib1,另外一个属性类型为MySingleSection,类型MySingleSection有2个string类型的属性。因为MySingleSection下并没有子节点,故该类需要继承自CongigurationElement,而SingleSectionHandler因为是一个section,所以该类需要继承自System.ConfigurationSection。
具体的实现代码如下:
从代码里可以看出了各个基类本身已经有了索引器。另外需要注意的是,配置的信息都是大小写敏感的。比如我们在类SingleSectionHandler中定义了属性MyAttrib1的标签[ConfigurationProperty("myAttrib1", DefaultValue = "默认值", IsRequired = true)],那么在config文件中属性的名字就必须是myAttrib1,大小写不能写错,而且MyAttrib1属性的实现中,使用索引器的时候也必须是get { return (String)this["myAttrib1"]; } set { this["myAttrib1"] = value; },索引器中的键名如果不是myAttrib1,即跟config中的属性名称不一样,那也是运行不成功的。
使用该配置的代码如下:
举例说明,假如我们需要实现一个如下的配置:
在这里customMulSectionDemo就是我们要定义的配置节,而配置节里面又包含一个regexUrlMapping元素,该元素有两个属性和一些子元素,我们选择的子元素比较特殊,它是n个add元素。使用的形式跟assSettings元素下面的add元素类似。那么如何实现这个自定义配置呢?
首先需要定义一个配置节元素,如下:
在这里,我们只讲解name和type属性的使用,其它属性的用法请参阅MSDN。name属性表示自定义配置节元素的名称。Type表示应该由哪个dll下哪个命名空间的哪个类来处理这个配置节。如上例中所写,CustomMulSection是dll的名称(可以从AssemblyInfo.cs文件中找到),CustomMulSection.RegexUrlMappingConfig是处理该配置节的类的全名称(包含命名空间)。
Ok,我们已经把目的明确了,下面的工作就是要实现RegexUrlMappingConfig这个类。要想此类拥有处理配置节的能力,就必须装饰一下这个类,装饰完成后,此类的代码如下:
首先,我们的类应该从ConfigurationSection类继承。这样它就有了处理自定义配置信息的能力。由于我们的配置节中只有一个regexUrlMapping元素,而且此元素包含了很多add元素。这种情况下我们使用了一个名为UrlMappings的属性来表示这个集合。为了表示该属性和元素之间的映射关系,我们需要以ConfigurationProperty自定义属性修饰UrlMappings。ConfigurationProperty类的参数” regexUrlMapping”指定了要映射的元素。get访问器中的代码非常程式化,这里不讲它的原理,只需要知道如此就可以实现对数据的访问。
下一步,就是实现UrlMappingCollection类。由名字可以得知,这是一个集合类,它一般用来处理包含add元素的元素。实现此类也需要使用自定义属性对此类进行装饰。如下:
可以看到,实现表示集合元素的类必须从ConfigurationElementCollection类继承。并且必须提供CreateNewElement和GetElementKey两个方法的重载。CreateNewElement其实是一个工厂方法,在此方法中,你必须返回一个表示一个add元素的对象,这样系统才能从web.config读取数据并形成一个集合。GetElementKey方法中,你需要返回一个可以表示为add元素键值的属性,方法的参数就是表示add元素的对象,该对象一定是从ConfigurationElement继承的,所以我们可以将其转换为一个我们自定义的配置对象,然后访问它的属性。在示例中我们返回了add元素的url属性值。因为这个方法是拿到一个对象对应的key,所以经常被其它方法调用以获取对象。
现在,我们已经实现了需要重写的方法。看到regexUrlMapping元素还包括两个属性,实现这两个属性的代码与已讲过的内容类似。在此不做赘述。
还差最后一步,就是实现表示add元素的类。如下:
唯一需要讲述的就是这个类必须从ConfigurationElement继承。其它的内容通过以上的讲述应该能够很好的理解。
至此,我们已经完成了配置的映射工作。
完整的代码如下所示:
app.config:
配置相关的解释类:
测试代码:
- 自定义配置节点中相关类的介绍 (返回)
- 自定义配置单节点 (返回)
- 向项目中添加System.Configuration引用。ConfigurationSection、ConfigurationElement、ConfigurationElementCollection这几个类都是在System.Configuration中定义的,而该dll默认并不是新建一个项目就有的,需要添加该dll引用。
- 假如我们要配置的节点格式如下:
- <?xml version="1.0" encoding="utf-8" ?>
- <configuration>
- <configSections>
- <section name="SingleSectionHandler" type="CustomSingleSection.SingleSectionHandler, CustomSingleSection, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
- </configSections>
- <SingleSectionHandler myAttrib1="lastBeachhead">
- <MySingleSection MyAttribute1="softwarezxj" MyAttribute2="epms"/>
- </SingleSectionHandler>
- </configuration>
具体的实现代码如下:
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Configuration;
- namespace CustomSingleSection
- {
- public class SingleSectionHandler : ConfigurationSection
- {
- public SingleSectionHandler()
- {
- }
- public SingleSectionHandler(String attribVal)
- {
- MyAttrib1 = attribVal;
- }
- [ConfigurationProperty("myAttrib1", DefaultValue = "默认值", IsRequired = true)]
- [StringValidator(InvalidCharacters = "~!@#$%^&*()[]{}/;'/"|//", MinLength = 1, MaxLength = 60)]
- public String MyAttrib1
- {
- get { return (String)this["myAttrib1"]; }
- set { this["myAttrib1"] = value; }
- }
- [ConfigurationProperty("MySingleSection")]
- public MySingleSection MySingleSection
- {
- get
- {
- return (MySingleSection)this["MySingleSection"];
- }
- set
- {
- this["MySingleSection"] = value;
- }
- }
- }
- public class MySingleSection : ConfigurationElement
- {
- public MySingleSection()
- {
- }
- public MySingleSection(String a1, String a2)
- {
- MyAttribute1 = a1;
- MyAttribute2 = a2;
- }
- [ConfigurationProperty("MyAttribute1", DefaultValue = "默认属性1", IsRequired = true)]
- [StringValidator(InvalidCharacters = "~!@#$%^&*()[]{}/;'/"|//", MinLength = 1, MaxLength = 60)]
- public String MyAttribute1
- {
- get{ return (String)this["MyAttribute1"]; }
- set{ this["MyAttribute1"] = value; }
- }
- [ConfigurationProperty("MyAttribute2", DefaultValue = "默认属性2", IsRequired = true)]
- [StringValidator(InvalidCharacters = "~!@#$%^&*()[]{}/;'/"|//", MinLength = 1, MaxLength = 60)]
- public String MyAttribute2
- {
- get{ return (String)this["MyAttribute2"]; }
- set{ this["MyAttribute2"] = value; }
- }
- }
- }
使用该配置的代码如下:
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Configuration;
- namespace CustomSingleSection
- {
- class Program
- {
- static void Main(string[] args)
- {
- LookCustomSingleSection();
- Console.ReadLine();
- }
- private static void LookCustomSingleSection()
- {
- SingleSectionHandler mySingleSection = ConfigurationManager.GetSection("SingleSectionHandler") as SingleSectionHandler;
- StringBuilder sb = new StringBuilder();
- sb.Append("该自定义配置节的属性MyAttrib1的值是:");
- sb.Append(mySingleSection.MyAttrib1.ToString());
- sb.Append("/n");
- sb.Append("该自定义配置节的MySingleConfigElement节点的MyAttribute1属性的值是:");
- sb.Append( mySingleSection.MySingleSection.MyAttribute1.ToString() );
- sb.Append("/n");
- sb.Append("该自定义配置节的MySingleConfigElement节点的MyAttribute2属性的值是:");
- sb.Append(mySingleSection.MySingleSection.MyAttribute2.ToString());
- sb.Append("/n");
- Console.WriteLine( sb.ToString() );
- }
- }
- }
举例说明,假如我们需要实现一个如下的配置:
- <customMulSectionDemo>
- <regexUrlMapping enable="true" rebaseClientPath="true">
- <add url="(/d+)$" mappedUrl="default.aspx?id=$1"></add>
- <add url="/$" mappedUrl="default.aspx?id=0"></add>
- </regexUrlMapping>
- </customMulSectionDemo>
首先需要定义一个配置节元素,如下:
- <configSections>
- <section name="customMulSectionDemo" type="CustomMulSection.RegexUrlMappingConfig,CustomMulSection" allowDefinition="Everywhere" restartOnExternalChanges="true" allowLocation="true"/>
- </configSections>
Ok,我们已经把目的明确了,下面的工作就是要实现RegexUrlMappingConfig这个类。要想此类拥有处理配置节的能力,就必须装饰一下这个类,装饰完成后,此类的代码如下:
- class RegexUrlMappingConfig : ConfigurationSection
- {
- [ConfigurationProperty("regexUrlMapping")]
- public UrlMappingCollection UrlMappings
- {
- get{return this["regexUrlMapping"] as UrlMappingCollection;}
- }
- }
下一步,就是实现UrlMappingCollection类。由名字可以得知,这是一个集合类,它一般用来处理包含add元素的元素。实现此类也需要使用自定义属性对此类进行装饰。如下:
- class UrlMappingCollection : ConfigurationElementCollection
- {
- protected override ConfigurationElement CreateNewElement()
- {
- return new UrlMapping();
- }
- protected override object GetElementKey(ConfigurationElement element)
- {
- return ((UrlMapping)element).Url;
- }
- [ConfigurationProperty("enable")]
- public bool Enable
- {
- get
- {
- return bool.Parse(this["enable"].ToString());
- }
- }
- [ConfigurationProperty("rebaseClientPath")]
- public bool RebaseClientPath
- {
- get
- {
- return bool.Parse(this["rebaseClientPath"].ToString());
- }
- }
- //写一个索引器,方便的访问该集合中的元素。
- //如果不写,则只有foreach来访问。
- public UrlMapping this[int index]
- {
- get
- {
- return this.BaseGet(index) as UrlMapping;
- }
- }
- }
现在,我们已经实现了需要重写的方法。看到regexUrlMapping元素还包括两个属性,实现这两个属性的代码与已讲过的内容类似。在此不做赘述。
还差最后一步,就是实现表示add元素的类。如下:
- class UrlMapping : ConfigurationElement
- {
- [ConfigurationProperty("mappedUrl")]
- public string MappedUrl
- {
- get
- {
- return (string)this["mappedUrl"];
- }
- }
- [ConfigurationProperty("url")]
- public string Url
- {
- get
- {
- return (string)this["url"];
- }
- }
- }
至此,我们已经完成了配置的映射工作。
完整的代码如下所示:
app.config:
- <?xml version="1.0" encoding="utf-8" ?>
- <configuration>
- <configSections>
- <section name="customMulSectionDemo" type="CustomMulSection.RegexUrlMappingConfig,CustomMulSection" allowDefinition="Everywhere" restartOnExternalChanges="true" allowLocation="true"/>
- </configSections>
- <customMulSectionDemo>
- <regexUrlMapping enable="true" rebaseClientPath="true">
- <add url="(/d+)$" mappedUrl="default.aspx?id=$1"></add>
- <add url="/$" mappedUrl="default.aspx?id=0"></add>
- </regexUrlMapping>
- </customMulSectionDemo>
- </configuration>
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Configuration;
- namespace CustomMulSection
- {
- class RegexUrlMappingConfig : ConfigurationSection
- {
- [ConfigurationProperty("regexUrlMapping")]
- public UrlMappingCollection UrlMappings
- {
- get{return this["regexUrlMapping"] as UrlMappingCollection;}
- }
- }
- class UrlMappingCollection : ConfigurationElementCollection
- {
- protected override ConfigurationElement CreateNewElement()
- {
- return new UrlMapping();
- }
- protected override object GetElementKey(ConfigurationElement element)
- {
- return ((UrlMapping)element).Url;
- }
- [ConfigurationProperty("enable")]
- public bool Enable
- {
- get
- {
- return bool.Parse(this["enable"].ToString());
- }
- }
- [ConfigurationProperty("rebaseClientPath")]
- public bool RebaseClientPath
- {
- get
- {
- return bool.Parse(this["rebaseClientPath"].ToString());
- }
- }
- //写一个索引器,方便的访问该集合中的元素。
- //如果不写,则只有foreach来访问。
- public UrlMapping this[int index]
- {
- get
- {
- return this.BaseGet(index) as UrlMapping;
- }
- }
- }
- class UrlMapping : ConfigurationElement
- {
- [ConfigurationProperty("mappedUrl")]
- public string MappedUrl
- {
- get
- {
- return (string)this["mappedUrl"];
- }
- }
- [ConfigurationProperty("url")]
- public string Url
- {
- get
- {
- return (string)this["url"];
- }
- }
- }
- }
测试代码:
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Configuration;
- namespace CustomMulSection
- {
- class Program
- {
- static void Main(string[] args)
- {
- DealMulSection();
- Console.ReadLine();
- }
- private static void DealMulSection()
- {
- RegexUrlMappingConfig myCustomMulSection = ConfigurationManager.GetSection("customMulSectionDemo") as RegexUrlMappingConfig;
- StringBuilder sb = new StringBuilder();
- sb.Append("myCustomMulSection对象的regexUrlMapping属性(实际是个集合)的enable:");
- sb.Append(myCustomMulSection.UrlMappings.Enable.ToString());
- sb.Append("/n");
- sb.Append("myCustomMulSection对象的regexUrlMapping属性(实际是个集合)的rebaseClientPath:");
- sb.Append(myCustomMulSection.UrlMappings.RebaseClientPath.ToString());
- sb.Append("/n");
- for (int i = 0; i < myCustomMulSection.UrlMappings.Count; i++ )
- {
- sb.Append("UrlMappings[");
- sb.Append(i.ToString());
- sb.Append("].url:");
- sb.Append(myCustomMulSection.UrlMappings[i].Url.ToString());
- sb.Append("/n");
- sb.Append("UrlMappings[");
- sb.Append(i.ToString());
- sb.Append("].mappedUrl:");
- sb.Append(myCustomMulSection.UrlMappings[i].MappedUrl.ToString());
- sb.Append("/n");
- }
- Console.WriteLine(sb.ToString());
- }
- }
- }