一目的
一般应用都有自己的配置文件如何将配置文件映射到NET中的对象是有现实意义的事情在Java中有一个digester开源项目实现了这个功能下面我一步一步来说明NET中如何更简单的实现他
二实现
定义xsd架构文件我们定义几个简单的架构
源文件如下
<?xml version= encoding=utf?>
<xs:schema id=MyConfig targetNamespace=ConfigTest elementFormDefault=qualified xmlns=ConfigTest xmlns:mstns=ConfigTest xmlns:xs=>
<xs:complexType name=select mixed=true>
<xs:sequence/>
<xs:attribute name=id type=xs:string />
<xs:attribute name=resultMap type=xs:string />
<xs:attribute name=cacheModel type=xs:string use=optional />
<xs:attribute name=sql type=xs:string />
</xs:complexType>
<xs:complexType name=update mixed=true>
<xs:sequence />
<xs:attribute name=id type=xs:string />
<xs:attribute name=parameterMap type=xs:string />
<xs:attribute name=sql type=xs:string />
</xs:complexType>
<xs:element name=statements>
<xs:complexType>
<xs:sequence>
<xs:element name=select type=select minOccurs= maxOccurs=unbounded />
<xs:element name=update type=update minOccurs= maxOccurs=unbounded />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
使用xsdexe生成对应于架构的配置类
xsdexe MyConfigxsd /c
//
// <autogenerated>
// This code was generated by a tool
// Runtime Version:
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated
// </autogenerated>
//
using SystemXmlSerialization;
//
// This source code was autogenerated by xsd Version=
//
namespace ConfigDll
{
/// <remarks/>
[SystemSerializableAttribute()]
[SystemXmlSerializationXmlTypeAttribute(Namespace = ConfigTest)]
[SystemXmlSerializationXmlRootAttribute(Namespace = ConfigTest IsNullable = false)]
public class statements
{
private select[] selectField;
private update[] updateField;
/// <remarks/>
[SystemXmlSerializationXmlElementAttribute(select)]
public select[] select
{
get
{
return thisselectField;
}
set
{
thisselectField = value;
}
}
/// <remarks/>
[SystemXmlSerializationXmlElementAttribute(update)]
public update[] update
{
get
{
return thisupdateField;
}
set
{
thisupdateField = value;
}
}
}
/// <remarks/>
[SystemSerializableAttribute()]
[SystemXmlSerializationXmlTypeAttribute(Namespace = ConfigTest)]
public class select
{
private string idField;
private string resultMapField;
private string cacheModelField;
private string sqlField;
/// <remarks/>
[SystemXmlSerializationXmlAttributeAttribute()]
public string id
{
get
{
return thisidField;
}
set
{
thisidField = value;
}
}
/// <remarks/>
[SystemXmlSerializationXmlAttributeAttribute()]
public string resultMap
{
get
{
return thisresultMapField;
}
set
{
thisresultMapField = value;
}
}
/// <remarks/>
[SystemXmlSerializationXmlAttributeAttribute()]
public string cacheModel
{
get
{
return thiscacheModelField;
}
set
{
thiscacheModelField = value;
}
}
/// <remarks/>
[SystemXmlSerializationXmlTextAttribute()]
public string sql
{
get
{
return thissqlField;
}
set
{
thissqlField = value;
}
}
}
/// <remarks/>
[SystemSerializableAttribute()]
[SystemXmlSerializationXmlTypeAttribute(Namespace = ConfigTest)]
public class update
{
private string idField;
private string parameterMapField;
private string sqlField;
/// <remarks/>
[SystemXmlSerializationXmlAttributeAttribute()]
public string id
{
get
{
return thisidField;
}
set
{
thisidField = value;
}
}
/// <remarks/>
[SystemXmlSerializationXmlAttributeAttribute()]
public string parameterMap
{
get
{
return thisparameterMapField;
}
set
{
thisparameterMapField = value;
}
}
/// <remarks/>
[SystemXmlSerializationXmlTextAttribute()]
public string sql
{
get
{
return thissqlField;
}
set
{
thissqlField = value;
}
}
}
}
实现IConfigurationSectionHandler接口
#region Using directives
using System;
using SystemCollectionsGeneric;
using SystemText;
using SystemIO;
using SystemReflection;
using SystemConfiguration;
using SystemXml;
using SystemXmlSerialization;
using SystemXmlSchema;
#endregion
namespace ConfigDll
{
public class MyConfigHandler : IConfigurationSectionHandler
{
private Type _configType = typeof(statements);
private string _schemaResourceName = ConfigDllMyConfigxsd;
private string _schemaNamespace = ConfigTest;
public MyConfigHandler()
{
}
public object Create(object parent object configContext SystemXmlXmlNode section)
{
XmlSerializer ser = new XmlSerializer(_configType);
// Create the XmlSchemaSet class
XmlSchemaSet sc = new XmlSchemaSet();
// Add the schema to the collection
Stream schemaStream = AssemblyGetAssembly(_configType)GetManifestResourceStream(_schemaResourceName);
scAdd(_schemaNamespace new XmlTextReader(schemaStream));
// Set the validation settings
XmlReaderSettings settings = new XmlReaderSettings();
settingsXsdValidate = true;
settingsSchemas = sc;
settingsValidationEventHandler += thisValidationEventHandle;
XmlReader reader = XmlReaderCreate(XmlReaderCreate(new StringReader(sectionOuterXml)) settings);
return serDeserialize(reader);
}
public void ValidationEventHandle(object sender ValidationEventArgs args)
{
ConsoleWriteLine(\t验证错误 + argsMessage);
}
}
}
当然你可以建一个通用的校验类这里只为演示
如果使用VS校验需要使用XmlValidatingReader类考虑到它在NET中已经过时所以使用新的方式
在AppConfig中使用自定义配置节点
<?xml version= encoding=utf ?>
<configuration>
<configSections>
<section name=statements type=ConfigDllMyConfigHandlerConfigDll />
</configSections>
<stat