也谈IConfigurationSectionHandler接口

IConfigurationSectionHandler接口也是大家讨论的比较多的接口之一,所以我在这也只能称为追追前人的尾巴,帮名为也谈.
实现该接口的用途或许大家都有些了解,主要是在配置文件中自点定配置节点.在web中有web.config,在win或者控制台程序中有
app.config.或者大家都使用过很多开源的框架,特别是一些IOC的项目,如:spring.net之类的.
当你使用他们的时候,需求一段的配置文件和XML文件,而配置文件节点中必有的<configSections></configSections>就是自定义节点的申明了.
下面引用一段spring.net的配置文件:
  1. <configuration>
  2.   <configSections>
  3.     <sectionGroup name="spring">
  4.       <section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core"/>
  5.       <section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" />
  6.     </sectionGroup>
  7.   </configSections>
  8.   <spring>
  9.     <context>
  10.       <resource uri="config://spring/objects"/>
  11.     </context>
  12.        
  13.     <objects xmlns="http://www.springframework.net">
  14.         ...
  15.     </objects>
  16.   </spring>
  17. </configuration>
然而你或者想知道 < section   name = "context"   type = "Spring.Context.Support.ContextHandler, Spring.Core" />这到底是什么?
这正是我们要求解的地方.因为在写此文的时候没有看过其他人的解说,所以内容皆为个人见解,不足之处还请拍砖.如有转载请注明作者和出处.谢谢.


IConfigurationSectionHandler正是处理上面让人感到疑惑的问题.

看看IConfigurationSectionHandler接口的定义:

  1. using System;
  2. using System.Xml;
  3. namespace System.Configuration
  4. {
  5.     // 摘要:
  6.     //     处理对特定的以前的配置节的访问。
  7.     public interface IConfigurationSectionHandler
  8.     {
  9.         // 摘要:
  10.         //     创建配置节处理程序。
  11.         //
  12.         // 参数:
  13.         //   p arent:
  14.         //     父对象。
  15.         //
  16.         //   s ection:
  17.         //     节 XML 节点。
  18.         //
  19.         //   configContext:
  20.         //     配置上下文对象。
  21.         //
  22.         // 返回结果:
  23.         //     创建的节处理程序对象。
  24.         object Create(object parent, object configContext, XmlNode section);
  25.     }
  26. }

该接口仅有一个方法,返回的是一个object.具体用处可以先来看看我们常用的在配置文件中设置数据库连接字符串的使用方法:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Configuration;//必须添加引用Configuration.dll
  5. namespace Entity
  6. {
  7.     public class Class1
  8.     {
  9.         private static ConnectionStringSettingsCollection col;
  10.         static Class1()
  11.         { 
  12.             try
  13.             {
  14.                 //应用程序或者控制台程序 app.config
  15.                 Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);                
  16.                 col = config.ConnectionStrings.ConnectionStrings;
  17.             }
  18.             catch
  19.             {
  20.                 try
  21.                 {
  22.                     //网站web.config
  23.                     col = ConfigurationManager.ConnectionStrings;
  24.                 }
  25.                 catch (Exception ex)
  26.                 {
  27.                     throw new DataBaseException(ex.Message, ex);
  28.                 }
  29.             }
  30.         }
  31.     }
  32. }
作为web开发的人员来说 ConfigurationManager.ConnectionStrings;这个正是常见到的,而我们也想通过
  ConfigurationManager类或者Configuration类直接获取配置文件里面的信息,并根据里面的配置信息返回我们想要的类型的话那就是实现IConfigurationSectionHandler接口,实现该接口后使用方式为:
(以下以我将开源的Logger项目为示例代码)

  1. object obj=ConfigurationManager.GetSection("Galbanum/Logger");

下面看看我的接口实现的代码:
  1.  /// <summary>
  2.     /// 该类实现IConfigurationSectionHandler接口,为通过获取配置信息并通过配置文件信息来创建ILoggerStyle
  3.     /// ILoggerStyle接口为日志样式接口。
  4.     /// </summary>
  5.     public class LoggerHandler : IConfigurationSectionHandler
  6.     {
  7.         //静态方法保存ILoggerStyle,用缓存也行,即节省每次使用时都需求读取配置信息的消耗
  8.         private static Dictionary<string, ILoggerStyle> dicLoggerStyle;
  9.         //静态构造,确保存dicLoggerStyle静态成员为单例。
  10.         static LoggerHandler()
  11.         {
  12.             dicLoggerStyle = new Dictionary<string, ILoggerStyle>();
  13.         }
  14.         #region IConfigurationSectionHandler 成员
  15.         //实现接口方法Create
  16.         public object Create(object parent, object configContext, System.Xml.XmlNode section)
  17.         {
  18.             ILoggerStyle style = null;
  19.             string key=string.Empty;
  20.             string value=string.Empty;
  21.             XmlNodeList nodes = section.SelectNodes("LoggerStyle");//获取配置文件中Logger节点的LoggerStyle所有子节点
  22.             foreach (XmlNode n in nodes)
  23.             {
  24.                 foreach (XmlAttribute att in n.Attributes)
  25.                 {
  26.                     if (att.Name == "key")
  27.                         key = att.Value;
  28.                     if (att.Name == "value")
  29.                         value = att.Value;
  30.                 }
  31.                 if (key != String.Empty && value != String.Empty)
  32.                 {
  33.                     style = LoggerStyleFactory.GetStyle(key, value);//通过反射工厂方法创建实例,该方法为internal
  34.                     dicLoggerStyle.Add(key, style);
  35.                 }
  36.                 else
  37.                 {
  38.                     throw new LoggerException("配置文件Logger节点出错。");
  39.                 }
  40.             }
  41.             return dicLoggerStyle;
  42.         }
  43.         #endregion
  44.     }
上面的代码应该是很简单的,再看看对应的配置文件:

  1. <configuration>
  2.   <configSections>
  3.     <sectionGroup name="Galbanum">
  4.       <section name="Logger" type="Logger.LoggerHandler,Logger"/>
  5.     </sectionGroup>
  6.   </configSections>
  7.   <Galbanum>
  8.     <Logger>
  9.       <LoggerStyle key="test" value="Entity.EntityStyle,Entity">
  10.       </LoggerStyle>
  11.       <LoggerStyle key="orm" value="Logger.OrmStyle,Logger">
  12.       </LoggerStyle>
  13.     </Logger>
  14.   </Galbanum>
  15. </configuration>

再看看调用的方法:
  1. private Dictionary<string, ILoggerStyle> dicStyle=ConfigurationManager.GetSection("Galbanum/Logger"as Dictionary<string,ILoggerStyle> ;
即你在你的项目的配置文件中配置上面的信息,在任何地址使用 =ConfigurationManager.GetSection( "Galbanum/Logger" )即可获取 IConfigurationSectionHandler接口中Create()方法的返回值 return  dicLoggerStyle;
很是不错吧?在网站项目和控制台或者应用程序项目中使用方式竟然是一样的,强大啊,在微软自己定义的Configuration节点中经常是web.config和app.config获取的方法是不相同的.而且返回的是一个object,一个类型转换就到了你想要的类型.如果你真的想强大一些的话你甚至可以自定义一个你自己的Configuration,哈哈,快去试试啊.


以上内容纯个人见解,如有误导敬请原谅。


你可能感兴趣的:(也谈IConfigurationSectionHandler接口)