<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="SimpleConfiguration" type="MySectionHandler,MyAssembly"> </section> </configSections> <SimpleConfiguration> <Module1> <section1> <key1>value1</key1> <key2>value2</key2> </section1> </Module1> <Module2> <section1> <key1>value1</key1> <key2>value2</key2> <section1> </Module2> </SimpleConfiguration>
如果建立了上述配置文件,您的目的就是要读取该文件中SimpleConfiguration部分的实体信息。要想实现这一点,就应该在.NET中添加以下代码:
|
此行代码可以引发一系列操作。进行上述调用时,.NET 将调用名为SimpleConfiguration的类(在文件中的 configSections部分)并且通过将一个XML结点传递给那个创建方法来调用熟知的Create方法。不论此Create方法返回何种类型的对象,该对象都将会传递给GetConfig(...)的调用者。为了给出一个更加完整的示例,下面就介绍一个此类型处理器的示例代码:
|
客户端与处理同种对象的section 处理器之间必须达成一致。在这种情况下,该对象就是指ArrayList。
上述方法有不少优点。调用者可获得一个C# 对象,此对象与每一个XML section相对应。您可以拥有数目不限的XML section。另一方面,为了简便起见,您需要做到:
1.为每一个 section 编写一个类。
2.解析 XML section 以便将其转变成相应的对象。
客户端常常希望拥有一个更简单的配置接口。下面就是这样一个简单的示例:
|
string value = AppServices.getValue( "/SimpleConfiguration/Module1/section1/key1", "defaultvalue");
API的这个版本在找不到关键字时,不但不会引发异常,相反将会返回已设置的默认值。例如,您可以进行如下操作:
|
通过降低错误率来使关键字不区分大小写也是完全可能的。此方法与Xpath相类似。注意到这一点,下面是该API的又一个版本:
|
有时候您可能会遇到一个给定的key对应多个结点。这种情况下,您可能希望收到的结点为XML结点。要实现这一点,可以进行如下操作:
|
我们再回到基本的AppServices.getValue(key)方法。有时,虽然这里的key是在XML文件中指定的,但它的内容却可能是空白符号。这种情况下,可将该key视为根本不存在。同样,也可以选择让API抛出一个异常。如果要兼顾到此种变化,可以调用另一函数:
|
概括一下,截止目前我们已经得到了下列这些函数:
|
我们在这里所采取的一切方法就是为了真正实现简化。具体实现时,可根据情况选择实现上述API之中的一部分。
将配置服务应用到一个实际的示例,我们将会对相关内容有更清晰的理解。在这个示例中,我们将在Web应用程序中发送电子邮件。可能您已经有了如下所示的一个API :
|
如果使用此 API,则客户端代码将是:
|
正如您所看到的,很难对电子邮件的所有参数进行编码以便嵌入到Web站点中。如果我们想从配置文件中读取这样的一些参数又会怎么样呢?
|
只要此配置适当,就可以将先前的方法更改为下面所示的方法:
|
将公共静态服务转变成接口
在讲述如何实现这些方法之前,我们先来解释如何将一个静态方法转变成为一个接口。具体理由如下:AppServices 是一个接口集,其中的每个接口均表示一种服务。例如:
|
我们来看看 IConfig可能包含的内容:
|
我们可能拥有另一支持XPath 的接口,如下所示:
|
现在,我们继续操作,将会得到一个如下所示的实现:
|
现在对 AppServices 进行编码,如下所示:
|
为什么要将静态方法转变成接口呢?这是因为对于一些情况,区分大小写是很有帮助的,但是对于另外一些情况,就没有必要区分大小写。而接口则可以很好地支持这两种情况:
|
应用程序服务在运行时将根据实际情况返回一个适当的实现。如果您想知道如何实现,可以参考工厂服务。或者您可以阅读一些参考文献。下面我们演示一个更完整的示例:
|
我们一直在强调配置文件的重要性,用不了多久,这种想法就会得到广泛应用。XML 配置文件将会随处可见。在一个团队中,可能需要将配置信息拆分成多个文件,以便增强团队成员之间的合作。
到目前为止,我们已经讨论了配置服务的优点以及如何使用配置服务的内容。这些内容应该说是经验的积累。接下来我们来看一些具体的实现。
方法是足够简单了。所有的配置均可以在一个section中设置。诸如 DefaultConfig 这样的类可以读取此section中的数据内容。一旦获取了所需的数据内容,DefaultConfig 类就可以遍历XML文档中的每一个结点,并在数据字典或哈希表中为每一个关键字和值设置对应的一项。这里所提到的数据字典将可以响应客户端发送的关键字请求。
Section 处理器代码如下:
|
DefaultConfig代码:
|
提示:编码时请特别关注如何处理 CDATA 和空文本结点。
在下一篇文章中,我们将在这种简单的配置服务基础之上对其进行扩展构成工厂服务FactoryService。工厂服务可以使您的体系结构变得更加灵活。