如果您是.NET 2.0配置的新手,或尚未掌握类型验证和转换的概念,您应该首先阅读以前的文章,可以在以下链接找到:
本文要讨论的内容如下:
4、Configuration Metadata
Let's go on!
配置,如果它需要一个系统,例如.NET 2.0提供的,通常是相当复杂的。这种配置通常是分层的,关系的和对一个或多个应用程序根本上关键支持灵活的、可复用、容易维护的架构。通常在如此复杂的应用程序架构中,需要更多关于配置的信息,除了配置设置自己。这种额外的信息也要求支持配置本身的适当执行,也可能支持使用配置的代码。值得庆幸的是,.NET 2.0配置框架充斥着元数据,暴露给你每次能想到的配置细节。
在这篇文章前面,我已经介绍过两个可能的环境中配置的基本分层结构:Exe文件的配置和Web应用程序的配置。这两个配置环境定义上下文,配置在里面加载、合并、保存和分解。上下文不仅仅是一个上下文,然而关于当前配置上下文的具体细节可以通过ContextInformation对象访问。ContextInformation对象仅在两个位置暴露…通过Configuration 对象和ConfigurationElement 对象(及其衍生类)。ContextInformation类很简单,提供访问更详细的上下文信息对象(HostingContext),以及一个标志(flag),标记当前配置对象是否是机器级配置。请注意,机器级配置天生地上下文少,在Exe和Web上下文中存在和表现得一样。
图10 The ContextInformation, ExeContext and WebContext classes
ExeContext 类是一个非常简单的类,仅提供了关于当前可执行应用程序的路径和加载配置对象的当前UserLevel的信息。此信息通常到一个配置对象被加载时才知道,但如果上下文通过ConfigurationElement 对象访问,不访问这个对象,ConfigurationUserLevel 未必必须要知道。
WebContext 类提供比ExeContext 更多的细节,因为配置层次结构在Web环境可能更加复杂。通过网络背景下,您可以访问该网站的名称、虚拟路径、应用程序的路径和配置对象或元素被加载的子路径。此外,您可以访问配置文件所驻留的WebApplicationLevel。根据配置是由一个根页面,子目录中的页面,或一个子Web应用程序访问,实际的*.config文件可能驻留在一个比使用该配置代码更高或更低的目录层次。
在.NET 2.0配置框架的所有元数据类中,ConfigurationProperty 应该是读了前面文章的读者最熟悉的。这个类提供途径,我们可以定义了配置在给定配置节和子元素中的实际设置。尽管它是熟悉的,应该澄清ConfigurationProperty 实际是关于一个配置元素设置的元数据,并不直接代表一个存储在*.config文件的XML。除了在自定义配置类定义哪些设置应该可用,ConfigurationProperty 类只在配置框架内部使用。
图11: The ConfigurationProperty and related classes
一个关于ConfigurationProperty 的有趣说明,他提供访问这两个非元数据、非配置,在.NET 2.0配置框架的支持类型。每个配置属性可能与一个类型转换器和验证器组合,以方便原生类型与字符串转换和验证属性值是否是一个原生类型。这两个支持类型在配置框架中提供很大的灵活性,使特定的字符串结构能存储在在一个XML文件,在反序列化时转换成原生了,可能非常复杂,的.NET类型(序列化时转换成字符串)。
在.NET 2.0配置框架中的所有元数据类中,ConfigurationElementProperty 是最奇怪的。这个类仅仅暴露单个属性——验证器。无论它奇怪与否,ConfigurationElementProperty 提供一个ConfigurationElement直接访问验证器以确保元素数据是否正确。序列化和反序列化 都将调用验证器以确保无效的数据必备读取或写入。ConfigurationElementProperty 一般分配在构造期间,当内部配置管理框架读取一个*.config文件和从定义的属性生成ConfigurationElements 。
不像ConfigurationElementProperty ,ElementInformation 提供一些关于配置元素的非常有用的元数据。要访问ElementInformation 对象必须要应用ConfigurationElement.ElementInformation 属性,因为这是框架暴露的唯一访问的。
Figure 12: The ElementInformation and related classes
这个对象提供一些基本的标志,指示元素是否是一个集合元素(IsCollection)、是否被锁(IsLocked)(仅能读但不能修改)、是否位于(IsPresent)配置文件中。最后一个属性,IsPresent,似乎有点奇怪。对于大多数时间,配置将是只能从配置文件读取。然而,当你修改一个配置文件,可能编程地添加元素、集合、甚至定义和添加整个配置节。当一个配置节被添加但没有保存到*.config文件,IsPresent会是FALSE。ElementInformation 对象也提供两个其他有用的小信息花絮:Source和LineNumber。Source属性返回磁盘上*.config文件的路径和文件名。当使用configSource属性,或<appSettings/>的文件属性,Source属性将发射到外部配置文件。LineNumber属性将返回在源文件中原属被读取的行号。
除了一些基本的标志和文件信息,ElementInformation 对象提供两个集合Properties和Errors。Properties集合暴露关于每个属性定义的元数据列表。PropertyInformation 类类似于ElementInformation 类,提供一些基本的标志和源文件信息关于每个个别的属性,以及一些特定配置属性的额外详细细节。很可能要检查一个属性的默认值是什么,并和当前值比较,一个很有用的小功能。使用过ConfigurationPropety 类和读了此系列前面的文章人应该熟悉PropertyInformation 暴露的大部分信息悉。
ElementInformation暴露的最后一个集合,Error,是另外一个由于得小宝石。一般来说,在反序列化是,当解析错误发生时,硬异常不会立即跑出。相反,一个ConfigurationException 将被创建和加入集合,它是后来由一个ConfigurationErrorsException暴露,包含反序列化期间发生的所有错误。ElementInformation 的Error集合提供访问相同的错误列表。根据错误发生在反序列化(或序列化,或配置元素的其他活动),列表可能不完整且可能存在其他问题。但是,他可以有助于确定在运行时配置发生了什么事,允许自动解决问题或报告配置问题。
SectionInformation是另外一个非常有用的元数据对象。这个对象提供了大量的允许和锁信息,以及提供一些有趣的加密和加载机制。在大部分情况下,这个类的允许和锁属性(properties)用各种属性(attributes)能在XML中设置。配置节允许和锁是一个重要的概念,在machine.config中用的非常广泛且当改变继承设置或编程地编辑他们时它可能是造成许多奇怪问题的根源之一。
图 13: The SectionInformation and related classes
(译注:作者写到这就没写了,可惜后面部分不会再写了。)
声明:此文是译文,实因水平有限,若有翻译不当之处请不吝指出,以免此译文误导他人,在此谢过! 如果您觉得还不错望不吝推荐,能让更多的人看到,使开发者们更轻松的使用.NET 2.0的配置框架——这是Jon Rista的目的,也是我翻译这个的心愿!此系列也终结了。
英文原文:Jon Rista,Cracking the Mysteries of .NET 2.0 Configuration