您的位置:首页 > 其它

IConfigurationSectionHandler 接口的实现

2010-12-10 09:06 337 查看
IConfigurationSectionHandler 这个接口网络讨论的太多了

我刚遇到这个问题,所以也发个实例出来,是我自己的一个框架项目里的一部分。

尽量写详细点,欢迎初学者研究。

下面是app.config web.config也可以的

<configuration>
<configSections>
<section name="Framework" type="CWF.ClassFactory.CWF_ConfigHandler,CWF.ClassFactory"/>
</configSections>
<Framework>
<ClassFactory>
<!-- DataProcess -->
<class name="CWF.AbstractSP" type="CWF.DataProcess.CWF_AbstractSP,CWF.DataProcess" />
<class name="CWF.SQL" type="CWF.DataProcess.CWF_SQL,CWF.DataProcess" />
<class name="CWF.Access" type="CWF.DataProcess.CWF_Access,CWF.DataProcess" />
<class name="CWF.Oracle" type="CWF.DataProcess.CWF_Oracle,CWF.DataProcess" />
<class name="CWF.ParamList" type="CWF.DataProcess.ParamList,CWF.DataProcess" />
<class name="CWF.SimpleProce" type="CWF.DataProcess.CWF_SimpleProce,CWF.DataProcess" />
<!--Service-->
<class name="CWF.ServiceFactroy" type="CWF.Service.CWF_ServiceFactroy,CWF.Service" />
<class name="CWF.AbstractDF" type="CWF.Service.CWF_AbstractDF,CWF.Service" />
<class name="CWF.DailyFile" type="CWF.Service.CWF_DailyFile,CWF.Service" />
</ClassFactory>
</Framework>

看到在configSections节点下我定义了一个section 节点,这个是段处理器节点,告诉程式他name属性里指的节点名(本例为“Framework”)采用那个处理程式(type属性),type属性就是该段处理程式的具体方法

type="CWF.ClassFactory.CWF_ConfigHandler,CWF.ClassFactory" 其中CWF.ClassFactory.CWF_ConfigHandler类实现了IConfigurationSectionHandler接口,CWF.ClassFactory是命名空间,以逗号相隔。具体的实现接口的办法下面将列出代码。

app.config里的Framework节点是我列出的类工厂里的所有类,设计思路是把底层的实体类和业务应用分开,才用了反射技术,当我们要调用一个类的时候只要告诉程式该类在app.config里的name(这个name也可以自定义),那么他就会读取class节点name属性匹配的节点的type属性,然后反射出该类给调用者使用。

这样的好处是我们不需要知道具体类的实际名称和属性,就可以调用它,并且底层类都写在app.config里,也不需要你打开api帮助文档,而且可以返回强类型对象,方便.net的智能提示我们编码。可能这样就会问了,反射是很灵活,但反射回来的是object对象,object是弱类型怎么能是强类型呢,其实我在反射上再封装了一层强类型转换而已。

下面就看看如何实现这个接口,方便的读取Framework下面的节点。

在实现这个功能之前首先要了解IConfigurationSectionHandler 是如何工作的。

该接口只有一个方法:

Create(ByVal parent As Object, ByVal configContext As Object, ByVal section As System.Xml.XmlNode) As Object

Create方法,我就是 要实现这个方法。

ConfigurationManager.GetSection("Framework") 这句话可能我们经常用,其实在我们调用GetSection(旧版本是: ConfigurationSettings.GetConfig)方法的时候他会调用Create方法,应为.NET下的这些类都实现了IConfigurationSectionHandler 接口,比如ConfigurationManager/ConfigurationSettings。

知道了他怎么运行的我们就可以搞定他了

Partial Class CWF_ConfigHandler
Implements IConfigurationSectionHandler
Public Function Create(ByVal parent As Object, ByVal configContext As Object, ByVal section As System.Xml.XmlNode) As Object Implements System.Configuration.IConfigurationSectionHandler.Create
Return New CWFConfiguration(section)
End Function
End Class

CWF_ConfigHandler类是我自定义的,他实现IConfigurationSectionHandler接口并完成Ceate方法,这里我还定义了一个类CWFConfiguration并把xmlnode类型的section作为实例参数传过去,然后我们就在该类里操作xml找到我们要的节点数据。

''' <summary>
''' 获取类工厂的type类型
''' </summary>
''' <remarks></remarks>
Public Class CWFConfiguration
Public FW As XmlNode
Public Sub New(ByVal frame As XmlNode)
FW = frame
End Sub
Public Function getClassType(ByVal className As String) As String
Try
Return FW.SelectSingleNode("//ClassFactory//class[@name='" & className & "']").Attributes("type").Value()
Catch ex As Exception
Return String.Empty
End Try
End Function
End Class

这里一个getClassType方法,返回type里的字符串 操作xml就不用多说了吧

我空间有xpath的详细说明。这样我们就找到了type里定义的类型。

下面看看如何调用:

Public Class CWF_GetFactory
''' <summary>
''' 获取类工厂里的类
''' </summary>
''' <param name="className">类名</param>
''' <returns>Object</returns>
''' <remarks></remarks>
Public Function getClass(ByVal className As String) As Object
Dim obj As Object = Nothing
Dim cm As CWFConfiguration = CType(ConfigurationManager.GetSection("Framework"), CWFConfiguration)
Dim t As String = cm.getClassType(className)
Dim type As System.Type = System.Type.GetType(t)
obj = Activator.CreateInstance(type)
Return obj
End Function
End Class

这个类获取我们要的用来获取type里定义的类型,其中一个getClass方法传递给他我们查找的name属性值就可以了

他返回需要的type,然后反射为type类型,实例化对象返回object,这样我们的工作就完成了。可能你看了这个操作过程会觉得没有必要这样做,反而麻烦。但是我们要在系统底层添加一个类,或删除一个类,就要修改类工厂,甚至更新全部关于该类工厂的所有引用,可能会导致整个工程换面,然而有了这层我们就只需要简单的改改配置文件就能添加或删除一个类工厂,对于程式可以不做任何的改动。

这里补充一点:ConfigurationManager 这个必须添加System.Configuration.dll的引用。

好了写到这里,欢迎留言探讨。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: