一.目的
一般应用都有自己的配置文件,如何将配置文件映射到.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>
<stat
闽公网安备 35060202000074号