这只是System.Web ASP.NET配置节组提供的一套完整的配置节的一小部分。这些设置都可以通过一个精巧包装的对象模型访问,它归根于System.Web.Configuration.SystemWebSectionGroup类。在事件的要求下,使用这个对象模型甚至可以将更新和保存回web.config文件,假设该代码有改变和保存的权限。
.NET 2.0配置系统用这个对象模型为我们处理解析、验证、安全和population(译注:关于 Population:这个词原型是Populate,有填充的含义。例如老外有时候表述给下拉列表增加列表项时,就说“Populate the list”。我想在文章里应该是指反序列话时往配置文件中写入配置元素吧)。除了编写自定义配置节,这是相当简单的,它完全去除了对XML的考虑,当在应用程序中使用你的配置时。不仅如此,在应用程序的任何地方都可以直接访问这个精美的包装、强类型、安全对象模型,而无需担心向注册表那样给自定义XML配置文件查找或存储文件路径。为不一致、不灵活、低性能的自定义配置管理器烦恼的时代一去不复返了。
3、编写一个基本的配置节
如果在这之前的东西吓到了你,别担心。编写代码来提供自定义配置节到你的应用程序非常简单。处理难看的XML、安全检查、类型转换等等绝大部分问题,已经被.NET 2.0框架中已有代码处理了。由于System.Configuration的一组基类集,要创建一个简单的配置节的实际代码量非常非常少。让我们开始创建一个含有一个字符串值、一个布尔值和一个时间跨度值的简单配置节。每一个配置节都必须继承ConfigurationSection基类,让我从以下内容开始:
using System;
using System.Configuration;
#endregion
namespace Examples.Configuration
{
/// <summary>
/// An example configuration section class.
/// </summary>
public class ExampleSection: ConfigurationSection
{
#region Constructors
static ExampleSection()
{
// Predefine properties here
}
#endregion
// Declare static property fields here
// Declare expose properties here
}
}
一旦你开始定义一个配置节类,你将必须定义有效的配置属性。一个配置属性,通过ConfigurationProperty类表示,描述了一个配置项,它将在你的配置节中可用。有两种方法定义配置属性,编程式(programmatic)和声明式(declarative)。这两种方法我个人都喜欢用,因为声明式方法有助于自描述的代码,编程式方法更严谨。这保证了只有你期望的确切的对象模型生成和支持,但是维护起来有些乏味,因为对一个配置属性两者都要更新。注:在这文章中,作为一个完整的例子我将使用这两种方法。
让我们开始往我们的示例配置节中填写代码。首先定义静态属性字段,然后在类的静态构造器中创建那些字段。最后通过编写C#属性暴露配置数据。自定义的配置节完整源码应该看起来像下面这样:
using System;
using System.Configuration;
#endregion
namespace Examples.Configuration
{
/// <summary>
/// An example configuration section class.
/// </summary>
public class ExampleSection: ConfigurationSection
{
#region Constructors
/// <summary>
/// Predefines the valid properties and prepares
/// the property collection.
/// </summary>
static ExampleSection()
{
// Predefine properties here
s_propString = new ConfigurationProperty(
"stringValue",
typeof(string),
null,
ConfigurationPropertyOptions.IsRequired
);
s_propBool = new ConfigurationProperty(
"boolValue",
typeof(bool),
false,
ConfigurationPropertyOptions.None
);
s_propTimeSpan = new ConfigurationProperty(
"timeSpanValue",
typeof(TimeSpan),
null,
ConfigurationPropertyOptions.None
);
s_properties = new ConfigurationPropertyCollection();
s_properties.Add(s_propString);
s_properties.Add(s_propBool);
s_properties.Add(s_propTimeSpan);
}
#endregion
#region Static Fields
private static ConfigurationProperty s_propString;
private static ConfigurationProperty s_propBool;
private static ConfigurationProperty s_propTimeSpan;
private static ConfigurationPropertyCollection s_properties;
#endregion
#region Properties
/// <summary>
/// Gets the StringValue setting.
/// </summary>
[ConfigurationProperty("stringValue", IsRequired=true)]
public string StringValue
{
get { return (string)base[s_propString]; }
}
/// <summary>
/// Gets the BooleanValue setting.
/// </summary>
[ConfigurationProperty("boolValue")]
public bool BooleanValue
{
get { return (bool)base[s_propBool]; }
}
/// <summary>
/// Gets the TimeSpanValue setting.
/// </summary>
[ConfigurationProperty("timeSpanValue")]
public TimeSpan TimeSpanValue
{
get { return (TimeSpan)base[s_propTimeSpan]; }
}
/// <summary>
/// Override the Properties collection and return our custom one.
/// </summary>
protected override ConfigurationPropertyCollection Properties
{
get { return s_properties; }
}
#endregion
}
}