为自定义配置的编辑提供”智能感知”的支持

当我们在设计一个框架的时候,必然会涉及一系列的配置。为了让使用者更好地使用你提供的框架,让他们能够容易地维护这些配置是一项基本的要求。对于一些配置过于复杂的框架,比如EnterLib,比如WCF,往往会提供一个配置的工具。但是,不过这样的配置工具是否提供,手工编译配置文件是在所难免的。如果在通过VS编辑配置的时候,能够提供智能感知和提示性描述的支持,这无疑会使配置的编辑变得非常的容易。这里是一个简单的例子。

一、配置文件的结构

假设我们设计一个MessageGenerator的组件,用于生成程序我们需要的文本消息,比如验证控件的验证消息,异常的消息等。消息的内容根据需要可以保存在数据库中或者是XML文件中,并且采用不同模式(粒度)的缓存(None、Single、Category和All)。我们采用插件式的设计,定义一个IMessageProvider接口用于从数据源中获取消息列表,两个具体的DbMessageProvider和XmlMessageProvider实现了这个接口。具体采用那个MessageProvider,通过配置来决定(defaultProvider),配置结构如下所示:

   1: <?xml version="1.0"?>
   2: <configuration>
   3:   <configSections>
   4:     <section name="artech.messages" type="Artech.Messages.MessagesSetting, Artech.Messages"/>
   5:   </configSections> 
   6:   <artech.messages defaultProvider="DbProvider" cachingMode="None">
   7:     <providers>
   8:       <add name="DbProvider"  type="Artech.Messages.DbMessageProvider, Artech.Messages" 
   9:            connectionString="" applicationName=""  />
  10:       <add name="XmlProvider" type="Artech.Messages.XmlMessageProvider, Artech.Messages" 
  11:            source="~/Messages.xml"/>      
  12:     </providers>
  13:   </artech.messages>  
  14: </configuration>

二、为配置定义XSD

为了在VS中编辑配置文件的时候获得智能感知的支持,我们需要为它定义XSD。整个XSD如下所示,结构比较清晰。不过在这里有几点需要强调:

  • 我们通过采用<xs:documentation>节点定义一些表述性的文字。当你通过VS编辑配置文件的时候,针对当前配置节点定义的这些文字将会以Tips的形式显示出来;
  • 在定义MessageProvider的schema的时候,我们将针对所有预定义MessageProvider的配置属性都定义出来(DbMessageProvider的applicationName和connectionStringName,以及XmlMessageProvider的source)。如果这些配置属性不是对于所有的MessageProvider都是必须的(比如name和type),将它们定义成可选属性;
  • 对于一些枚举,或者限定在某个列表范围内固定的值,通过<xs:restriction>/<xs:enumeration>来定义,比如这里使用到的CachingMode。
   1: <?xml version="1.0" encoding="utf-8"?>
   2: <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" >
   3:   <xs:element name="artech.messages" type="MessagesConfigSection"/>
   4:   <!--MessagesConfigSection-->
   5:   <xs:complexType name="MessagesConfigSection">
   6:     <xs:choice minOccurs="0" maxOccurs="unbounded">
   7:       <xs:element name="providers" minOccurs="1" maxOccurs="1">
   8:         <xs:complexType>
   9:           <xs:sequence>
  10:             <xs:element name="add" type="MessageProvider" minOccurs="1" maxOccurs="unbounded"/>
  11:           </xs:sequence>
  12:         </xs:complexType>
  13:       </xs:element>
  14:     </xs:choice>    
  15:     <xs:attribute name="defaultProvider" type="xs:string" use="required">
  16:       <xs:annotation>
  17:         <xs:documentation>The configuration name of the default MessageProvider.</xs:documentation>
  18:       </xs:annotation>
  19:     </xs:attribute>
  20:     <xs:attribute name="cachingMode" type="CachingMode" use="optional">
  21:       <xs:annotation>
  22:         <xs:documentation>The caching mode (None, Single, Category, All).</xs:documentation>
  23:       </xs:annotation>
  24:     </xs:attribute>    
  25:   </xs:complexType>
  26:   <!--MessageProvider-->
  27:   <xs:complexType name="MessageProvider">
  28:     <xs:attribute name="name" use="required">
  29:       <xs:annotation>
  30:         <xs:documentation>A friendly name of MessageProvider.</xs:documentation>
  31:       </xs:annotation>
  32:     </xs:attribute>
  33:     <xs:attribute name="type" type="MessageProviderTypes" use="required">
  34:       <xs:annotation>
  35:         <xs:documentation>The assembly qualified name of the MessageProvider type.</xs:documentation>
  36:       </xs:annotation>
  37:     </xs:attribute>
  38:     <xs:attribute name="connectionString" type="xs:string" use="optional">
  39:       <xs:annotation>
  40:         <xs:documentation>[DbMessageProvider]The connection string configuration name.</xs:documentation>
  41:       </xs:annotation>
  42:     </xs:attribute>
  43:     <xs:attribute name="applicationName" type="xs:string" use="optional">
  44:       <xs:annotation>
  45:         <xs:documentation>[DbMessageProvider]The name of application.</xs:documentation>
  46:       </xs:annotation>
  47:     </xs:attribute>
  48:     <xs:attribute name="source" type="xs:string" use="optional">
  49:       <xs:annotation>
  50:         <xs:documentation>[XMLMessageProvider] The path of the XML file to store message entry list.</xs:documentation>
  51:       </xs:annotation>
  52:     </xs:attribute>
  53:   </xs:complexType>
  54:   <!--CachingMode-->
  55:   <xs:simpleType name="CachingMode">
  56:     <xs:restriction base="xs:string">
  57:       <xs:enumeration value="None"/>
  58:       <xs:enumeration value="Single"/>
  59:       <xs:enumeration value="Category"/>
  60:       <xs:enumeration value="All"/>
  61:     </xs:restriction>
  62:   </xs:simpleType>
  63:   <!--MessageProviderTypes-->
  64:   <xs:simpleType name="MessageProviderTypes">
  65:     <xs:restriction base="xs:string">
  66:       <xs:enumeration value="Artech.Messages.DbMessageProvider, Artech.Messages"/>
  67:       <xs:enumeration value="Artech.Messages.XmlMessageProvider, Artech.Messages"/>
  68:     </xs:restriction>
  69:   </xs:simpleType>
  70: </xs:schema>

三、应用XSD以获得职能感知的支持

如果这样一个XSD已经定义好,在对配置文件进行编辑的时候,通过VS的菜单XML\Schemas打开XML Schemas对话框。点击Add按钮将这个XSD文件添加近来,并Use属性设置成Use this schema。这样你编译配置文件的时候就可以获得只能感知的支持了,配置将会变得非常的容易,即使对配置结构不太了解的人也能根据智能感知和提示性的描述完成配置工作。

image

posted @ 2011-04-20 16:00  Artech  阅读(5997)  评论(25编辑  收藏  举报