一.目的 一般应用都有自己的配置文件,如何将配置文件映射到.NET中的对象是有现实意义的事情,在Java中有一个digester开源项目实现了这个功能,下面我一步一步来说明.NET中如何更简单的实现他 二.实现 1.定义xsd架构文件,我们定义几个简单的架构
 源文件如下: <?xml version="1.0" encoding="utf-8"?> <xs:schema id="MyConfig" targetNamespace="ConfigTest" elementFormDefault="qualified" xmlns="ConfigTest" xmlns:mstns="ConfigTest" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <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="0" maxOccurs="unbounded" /> <xs:element name="update" type="update" minOccurs="0" maxOccurs="unbounded" /> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>
2.使用xsd.exe生成对应于架构的配置类 xsd.exe MyConfig.xsd /c
//------------------------------------------------------------------------------ // <autogenerated> // This code was generated by a tool. // Runtime Version:2.0.40607.16 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // </autogenerated> //------------------------------------------------------------------------------
using System.Xml.Serialization;
// // This source code was auto-generated by xsd, Version=2.0.40607.16. // namespace ConfigDll {
/// <remarks/> [System.SerializableAttribute()] [System.Xml.Serialization.XmlTypeAttribute(Namespace = "ConfigTest")] [System.Xml.Serialization.XmlRootAttribute(Namespace = "ConfigTest", IsNullable = false)] public class statements {
private select[] selectField;
private update[] updateField;
/// <remarks/> [System.Xml.Serialization.XmlElementAttribute("select")] public select[] select { get { return this.selectField; } set { this.selectField = value; } }
/// <remarks/> [System.Xml.Serialization.XmlElementAttribute("update")] public update[] update { get { return this.updateField; } set { this.updateField = value; } } }
/// <remarks/> [System.SerializableAttribute()] [System.Xml.Serialization.XmlTypeAttribute(Namespace = "ConfigTest")] public class select {
private string idField;
private string resultMapField;
private string cacheModelField;
private string sqlField;
/// <remarks/> [System.Xml.Serialization.XmlAttributeAttribute()] public string id { get { return this.idField; } set { this.idField = value; } }
/// <remarks/> [System.Xml.Serialization.XmlAttributeAttribute()] public string resultMap { get { return this.resultMapField; } set { this.resultMapField = value; } }
/// <remarks/> [System.Xml.Serialization.XmlAttributeAttribute()] public string cacheModel { get { return this.cacheModelField; } set { this.cacheModelField = value; } }
/// <remarks/> [System.Xml.Serialization.XmlTextAttribute()]
public string sql { get { return this.sqlField; } set { this.sqlField = value; } } }
/// <remarks/> [System.SerializableAttribute()] [System.Xml.Serialization.XmlTypeAttribute(Namespace = "ConfigTest")] public class update {
private string idField;
private string parameterMapField;
private string sqlField;
/// <remarks/> [System.Xml.Serialization.XmlAttributeAttribute()] public string id { get { return this.idField; } set { this.idField = value; } }
/// <remarks/> [System.Xml.Serialization.XmlAttributeAttribute()] public string parameterMap { get { return this.parameterMapField; } set { this.parameterMapField = value; } }
/// <remarks/> [System.Xml.Serialization.XmlTextAttribute()] public string sql { get { return this.sqlField; } set { this.sqlField = value; } } } }
3.实现IConfigurationSectionHandler接口
#region Using directives
using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Reflection; using System.Configuration; using System.Xml; using System.Xml.Serialization; using System.Xml.Schema;
#endregion
namespace ConfigDll { public class MyConfigHandler : IConfigurationSectionHandler { private Type _configType = typeof(statements); private string _schemaResourceName = "ConfigDll.MyConfig.xsd"; private string _schemaNamespace = "ConfigTest";
public MyConfigHandler() { }
public object Create(object parent, object configContext, System.Xml.XmlNode section) { XmlSerializer ser = new XmlSerializer(_configType);
// Create the XmlSchemaSet class. XmlSchemaSet sc = new XmlSchemaSet();
// Add the schema to the collection. Stream schemaStream = Assembly.GetAssembly(_configType).GetManifestResourceStream(_schemaResourceName); sc.Add(_schemaNamespace, new XmlTextReader(schemaStream));
// Set the validation settings. XmlReaderSettings settings = new XmlReaderSettings(); settings.XsdValidate = true; settings.Schemas = sc; settings.ValidationEventHandler += this.ValidationEventHandle;
XmlReader reader = XmlReader.Create(XmlReader.Create(new StringReader(section.OuterXml)), settings); return ser.Deserialize(reader); }
public void ValidationEventHandle(object sender, ValidationEventArgs args) { Console.WriteLine("\t验证错误:" + args.Message); }
} } 当然你可以建一个通用的校验类,这里只为演示 如果使用VS2003,校验需要使用XmlValidatingReader类,考虑到它在.NET2.0中已经过时所以使用新的方式
4.在App.Config中使用自定义配置节点 <?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="statements" type="ConfigDll.MyConfigHandler,ConfigDll" /> </configSections> <statements xmlns="ConfigTest"> <select id="GetEmailAddressViaResultClass" resultClass="string"> select Account_Email as value from Accounts where Account_ID = #value# </select> <select id="GetAllEmailAddressesViaResultClass" resultClass="string"> select Account_Email from Accounts order by Account_ID </select> <update id="UpdateAccountViaParameterMap" parameterMap="update-params"> update Accounts set Account_FirstName = ?, Account_LastName = ?, Account_Email = ? where Account_ID = ? </update> <update id="UpdateAccountViaParameterMap2" parameterMap="update-params2"> update Accounts set Account_ID = ?, Account_FirstName = ?, Account_LastName = ?, Account_Email = ? where Account_ID = ? </update> </statements> </configuration> 注意:设置上Handler 在应用程序中得到配置 statements sts = (statements)ConfigurationSettings.GetConfig("statements");
5.在其他配置文件中使用 XmlDocument doc = new XmlDocument(); doc.Load("Extend_Test.xml"); statements sts = (statements)new MyConfigHandler().Create(null, null, doc.DocumentElement);
三.其他 环境:VS2005 难成好文章,只是凑凑热闹 
|