接下来的 EvaluateRecursive 方法将会调用 System.Configuration.NameValueFileSectionHandler 类的接口方法 Create
private object EvaluateRecursive(IConfigurationSectionHandler factory, object config, string[] keys, int iKey, XmlTextReader reader)
{
string text = keys[iKey];
int depth = reader.Depth;
do
{
if (!reader.Read())
{
break;
}
}
while (reader.NodeType != XmlNodeType.Element);
while (reader.Depth == (depth + 1))
{
if (reader.Name == text)
{
if (iKey < (keys.Length - 1))
{
config = this.EvaluateRecursive(factory, config, keys, iKey + 1, reader);
continue;
}
CreatePermissionSetFromLocation(this._filename).PermitOnly();
try
{
int line = reader.LineNumber;
try
{
ConfigXmlDocument document = new ConfigXmlDocument();
document.LoadSingleElement(this._filename, reader);
config = factory.Create(config, null, document.DocumentElement);
//调用 System.Configuration.NameValueFileSectionHandler 类的方法了,
下面要进入 System.Configuration.NameValueFileSectionHandler 类的分析了。
}
catch (ConfigurationException)
{
throw;
}
catch (XmlException)
{
throw;
}
catch (Exception exception)
{
throw new ConfigurationException(SR.GetString("Exception_in_config_section_handler"), exception, this._filename, line);
}
continue;
}
finally
{
CodeAccessPermission.RevertPermitOnly();
}
}
this.StrictSkipToNextElement(reader);
}
return config;
}
IConfigurationSectionHandler 接口成员 由所有配置节处理程序实现,以分析配置节的 XML。返回的对象被添加到配置集合中,并通过 GetConfig 访问。
object Create(
object parent,
object configContext,
XmlNode section
);
IConfigurationSectionHandler 接口是我们写自定义配置节点项时必须要实现的接口。下面再说。 NameValueFileSectionHandler 类的定义
public class NameValueFileSectionHandler : IConfigurationSectionHandler
{
// Methods
public NameValueFileSectionHandler();
public object Create(object parent, object configContext, XmlNode section);
}
NameValueFileSectionHandler.Create 方法的实现非常简单,就是获取 参数中 XmlNode section 的数据,通过 key 和 value 对应的关系 保存到 私有的 HashTable类型的变量中 section 的参数值大概是这样的
<appSettings>
<add key="ConnectionString" value="xxxxxxxxxx" />
<add key="__SystemID__" value="xxxxxxxxxx" />
</appSettings>
分析了 System.Configuration.ConfigurationSettings 类 后,来看看如何实现我们自定义的配置节点管理。 下面的示例代码我采用 VS.NET 的企业代码示例 Duwamish 项目来说明。
第一步,我们要自定义配置节点,web.config 配置节点示例如下:
<configuration>
<configSections>
<section name="DuwamishConfiguration" type="Duwamish7.Common.DuwamishConfiguration, Duwamish7.Common" />
</configSections>
</configuration>
<DuwamishConfiguration> //注意这里就是自定义配置项节点了
<add key="Duwamish.DataAccess.ConnectionString" value="server=.;User ID=sa;Password=password;database=Duwamish;Connection Reset=FALSE" />
<add key="Duwamish.Web.EnablePageCache" value="True" />
<add key="Duwamish.Web.PageCacheExpiresInSeconds" value="3600" />
<add key="Duwamish.Web.EnableSsl" value="False" />
</DuwamishConfiguration>
第二步,让我们的自定义配置节点处理类实现 IConfigurationSectionHandler 接口
在这里是 dll名称为 Duwamish7.Common 的 Duwamish7.Common.DuwamishConfiguration的类要实现这个接口代码:
public Object Create(Object parent, object configContext, XmlNode section)
{
NameValueCollection settings;
try
{
NameValueSectionHandler baseHandler = new NameValueSectionHandler();
settings = (NameValueCollection)baseHandler.Create(parent, configContext, section);
}
catch
{
settings = null;
}
if ( settings == null )
{
dbConnectionString = DATAACCESS_CONNECTIONSTRING_DEFAULT;
pageCacheExpiresInSeconds = WEB_PAGECACHEEXPIRESINSECONDS_DEFAULT;
enablePageCache = WEB_ENABLEPAGECACHE_DEFAULT;
enableSsl = WEB_ENABLESSL_DEFAULT;
}
else
{
dbConnectionString = ApplicationConfiguration.ReadSetting(settings, DATAACCESS_CONNECTIONSTRING, DATAACCESS_CONNECTIONSTRING_DEFAULT);
pageCacheExpiresInSeconds = ApplicationConfiguration.ReadSetting(settings, WEB_PAGECACHEEXPIRESINSECONDS, WEB_PAGECACHEEXPIRESINSECONDS_DEFAULT);
enablePageCache = ApplicationConfiguration.ReadSetting(settings, WEB_ENABLEPAGECACHE, WEB_ENABLEPAGECACHE_DEFAULT);
enableSsl = ApplicationConfiguration.ReadSetting(settings, WEB_ENABLESSL, WEB_ENABLESSL_DEFAULT);
}
return settings;
}
第三步,如何启动我们的自定义配置节点处理类
System.Configuration.ConfigurationSettings.GetConfig("DuwamishConfiguration");
到此,我们就搞掂了自定义配置节点管理了。自定义配置节点管理可以避免将很多的配置信息都放到 appSettings 节点中,便于管理。通过类来管理配置信息,可以在多个项目中重用,我们也可以写一个基类,来获取统一的配置项键管理。如在我们的项目中差不多每个 web.config 都会有
<add key="__SystemID__" value="xxxx" />
<add key="__SystemName__" value="xxxx" />
<add key="__SystemPassword__" value="xxxx" />
如果我们的基类提供了获取这三个对应 key 值的配置项,其它的项目需要扩展时,只须继承我们的配置节点管理基类就OK了。
|