RFID会议签到系统总结(五)――系统配置(上)

本文介绍了一种使用.NET Framework进行XML配置管理的方法。通过自定义配置节和实现IConfigurationSectionHandler接口,实现了配置文件的灵活管理。文章详细展示了配置设置类的设计及配置节处理程序的实现。

<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 

由于在XML处理方面的长足进步,现在写程序在配置方面比之以前是方便多了。比如在.net 1.1里,对于很简单的配置,用<appSettings>节就可以轻而易举的解决问题,你要读取配置一行代码就解决问题了。即使是要配置的变量稍微多一点,但化繁为简后用上述方法也可以胜任。(不过我看到过上百个<add key=”” value=”” />在同一个配置文件里,这样的话呢就太恐怖了,不知那是如何维护的)

这个系统要配置的东西不算很多,不过有几点比较的棘手。首先是有些变量是要求可写的,比较象数据库连接,象签到终端所属的管控端地址等,这些东西不是你程序安装时配置好就行的。再就是有些变量之间是有结构、有层次的,比如关于硬件方面的配置,一种硬件设备就有一组配置;比如象管控端程序的菜单呀,工具栏呀这些东西,每一项都带很多参数,一项项地再层层组成一个大集合。最后就是程序可能是不止一个配置文件的(管控端程序就是分为几个配置文件的)。这样势必得自己在配置管理方面下点功夫,不能直接用Framework里现成的了。

现成的东西是不能用了,但在Framework里半现成的还是有,我们可以自定义配置节,然后自己实现配置节处理程序,这样在应用端跟现成的基本没什么区别了。

.net 1.1里,所有的配置节处理程序都必须实现IConfigurationSectionHandler这个接口,这个接口只有Create这么一个方法,在这个方法里我们可以决定如何分析配置节的XML,以向外提供一个系统可以认识的一种配置结构。我很顺理成章的就决定用XML序列化的方法来实现配置文件XML字串与配置设置类之间的转化。

第一步先要设计一些配置设置的类,签到终端程序的配置基本上可以分下数据库、通讯、硬件及其他这四个部分(在管控端还有菜单、工具栏等等)。类的设计没什么好说的,重要的就是要注意一些XmlAttribute的运用,这些东西在XML序列化时会派上用场。关于配置设置类举一个简单但比较齐全的例子,其中即有Element,又有Attribute,而且还有不用序列化的属性。

下面是数据方面的配置设置

ContractedBlock.gifExpandedBlockStart.gif数据访问、数据同步配置类
None.gif    [XmlRoot("Data")]
None.gif
None.gif    
public sealed class DataCfg
None.gif
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif{
InBlock.gif
InBlock.gif       
public DataCfg()
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif       
dot.gif{
InBlock.gif
InBlock.gif           
//
InBlock.gif
InBlock.gif           
// TODO: 在此处添加构造函数逻辑
InBlock.gif
InBlock.gif           
//
InBlock.gif

ExpandedSubBlockEnd.gif       }

InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif       
private string _Local;
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif       
/**//// 本地数据库连接
InBlock.gif
InBlock.gif
#if Server
InBlock.gif
InBlock.gif       [XmlAttribute(
"Connection")]
InBlock.gif
InBlock.gif
#else
InBlock.gif
InBlock.gif       [XmlAttribute()]
InBlock.gif
InBlock.gif
#endif
InBlock.gif
InBlock.gif       
public string Local
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif       
dot.gif{
InBlock.gif
InBlock.gif           
get
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif           
dot.gif{
InBlock.gif
InBlock.gif              
return _Local;
InBlock.gif
ExpandedSubBlockEnd.gif           }

InBlock.gif
InBlock.gif           
set
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif           
dot.gif{
InBlock.gif
InBlock.gif              
if (this._Local!= value)
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif              
dot.gif{
InBlock.gif
InBlock.gif                  
this._Local = value;
InBlock.gif
InBlock.gif                  _LocalConnection 
= Decrypt(value);
InBlock.gif
ExpandedSubBlockEnd.gif              }

InBlock.gif
ExpandedSubBlockEnd.gif           }

InBlock.gif
ExpandedSubBlockEnd.gif       }

InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif       
private string _LocalConnection;
InBlock.gif
InBlock.gif       [XmlIgnore()]
InBlock.gif
InBlock.gif       
public string LocalConnection
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif       
dot.gif{
InBlock.gif
InBlock.gif           
get 
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif           
dot.gif{
InBlock.gif
InBlock.gif              
return _LocalConnection;
InBlock.gif
ExpandedSubBlockEnd.gif           }

InBlock.gif
InBlock.gif           
set 
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif           
dot.gif{
InBlock.gif
InBlock.gif              
if (_LocalConnection != value)
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif              
dot.gif{
InBlock.gif
InBlock.gif                  _LocalConnection 
= value;
InBlock.gif
InBlock.gif                  _Local 
= Encrypt(value);
InBlock.gif
ExpandedSubBlockEnd.gif              }

InBlock.gif
ExpandedSubBlockEnd.gif           }

InBlock.gif
InBlock.gif 
InBlock.gif
ExpandedSubBlockEnd.gif       }

InBlock.gif
InBlock.gif   
InBlock.gif
InBlock.gif
#if !Server
InBlock.gif
InBlock.gif       
private string _Remote;
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif       
/**//// 远程数据库连接
InBlock.gif
InBlock.gif       [XmlAttribute()]     
InBlock.gif
InBlock.gif       
public string Remote
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif       
dot.gif{
InBlock.gif
InBlock.gif           
get
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif           
dot.gif{
InBlock.gif
InBlock.gif              
return _Remote;
InBlock.gif
ExpandedSubBlockEnd.gif           }

InBlock.gif
InBlock.gif           
set
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif           
dot.gif{
InBlock.gif
InBlock.gif              
if (this._Remote != value)
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif              
dot.gif{
InBlock.gif
InBlock.gif                  
this._Remote = value;
InBlock.gif
InBlock.gif                  _RemoteConnection 
= Decrypt(value);
InBlock.gif
ExpandedSubBlockEnd.gif              }

InBlock.gif
ExpandedSubBlockEnd.gif           }

InBlock.gif
ExpandedSubBlockEnd.gif       }

InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif       
private string _RemoteConnection;
InBlock.gif
InBlock.gif       [XmlIgnore()]
InBlock.gif
InBlock.gif       
public string RemoteConnection
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif       
dot.gif{
InBlock.gif
InBlock.gif           
get 
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif           
dot.gif{
InBlock.gif
InBlock.gif              
return _RemoteConnection;
InBlock.gif
ExpandedSubBlockEnd.gif           }

InBlock.gif
InBlock.gif           
set
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif           
dot.gif{
InBlock.gif
InBlock.gif              
if (_RemoteConnection != value)
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif              
dot.gif{
InBlock.gif
InBlock.gif                  
this._RemoteConnection = value;
InBlock.gif
InBlock.gif                  _Remote 
= Encrypt(value);
InBlock.gif
ExpandedSubBlockEnd.gif              }

InBlock.gif
ExpandedSubBlockEnd.gif           }

InBlock.gif
ExpandedSubBlockEnd.gif       }

InBlock.gif
InBlock.gif   
InBlock.gif
InBlock.gif       
private int _DetectInterval;
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif       
/**//// 数据库连接检测间隔
InBlock.gif
InBlock.gif       [XmlElement(
"Detect-ms")]
InBlock.gif
InBlock.gif       
public int DetectInterval
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif       
dot.gif{
InBlock.gif
InBlock.gif           
get
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif           
dot.gif{
InBlock.gif
InBlock.gif              
return _DetectInterval;
InBlock.gif
ExpandedSubBlockEnd.gif           }

InBlock.gif
InBlock.gif           
set
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif           
dot.gif{
InBlock.gif
InBlock.gif              
if (this._DetectInterval != value)
InBlock.gif
InBlock.gif                  
this._DetectInterval = value;
InBlock.gif
ExpandedSubBlockEnd.gif           }

InBlock.gif
ExpandedSubBlockEnd.gif       }

InBlock.gif
InBlock.gif   
InBlock.gif
InBlock.gif       
private int _SyncInterval;
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif       
/**//// 数据同步间隔
InBlock.gif
InBlock.gif       [XmlElement(
"Sync-ms")]
InBlock.gif
InBlock.gif       
public int SyncInterval
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif       
dot.gif{
InBlock.gif
InBlock.gif           
get
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif           
dot.gif{
InBlock.gif
InBlock.gif              
return _SyncInterval;
InBlock.gif
ExpandedSubBlockEnd.gif           }

InBlock.gif
InBlock.gif           
set
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif           
dot.gif{
InBlock.gif
InBlock.gif              
if (this._SyncInterval != value)
InBlock.gif
InBlock.gif                  
this._SyncInterval = value;
InBlock.gif
ExpandedSubBlockEnd.gif           }

InBlock.gif
ExpandedSubBlockEnd.gif       }

InBlock.gif
InBlock.gif
#endif
InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif       
private string Encrypt(string plainText)
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif       
dot.gif{
InBlock.gif
InBlock.gif           
return Cryptographer.EncryptSymmetric(plainText);
InBlock.gif
ExpandedSubBlockEnd.gif       }

InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif       
private string Decrypt(string encryptedText)
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif       
dot.gif{
InBlock.gif
InBlock.gif           
return Cryptographer.DecryptSymmetric(encryptedText);
InBlock.gif
ExpandedSubBlockEnd.gif       }

InBlock.gif
InBlock.gif 
InBlock.gif
ExpandedBlockEnd.gif    }

None.gif
None.gif


 

(因为这个配置设置类在管控端只需要一个数据库连接串即可,但为此多写一个类又觉得心有不甘,所以偷懒加了个编译指令双方可以共用)

相应的在配置文件里的配置就象下面这个样子:

    <Data Local="DGkDBWoADigKLAIMkiOk+vy5sd5Dg=="

       Remote="DGnRBWoADiH4jOnb4uqjdE5ZQmEIsVw==">

       <Detect-ms>1000</Detect-ms>

       <Sync-ms>1000</Sync-ms>

    </Data>

 

二头的东西都具备,现在写中间的配置节处理程序。因为配置节比较多,而且每一个处理程序的写法都是一样的,所以又多了个处理程序的基类。

ContractedBlock.gifExpandedBlockStart.gif自定义配置节处理程序的基类
ExpandedBlockStart.gifContractedBlock.gif    public class CustomSectionHandlerBase : IConfigurationSectionHandler dot.gif
InBlock.gif
InBlock.gif       
protected Type sectionObjectType;
InBlock.gif
InBlock.gif 
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif       
public CustomSectionHandlerBase()dot.gif{
InBlock.gif
InBlock.gif           sectionObjectType 
= (Type)HandlerSectionObjectMap.Dictionary[this.GetType().AssemblyQualifiedName];
InBlock.gif
ExpandedSubBlockEnd.gif       }

InBlock.gif
InBlock.gif 
InBlock.gif
ContractedSubBlock.gifExpandedSubBlockStart.gif       
IConfigurationSectionHandler 成员#region IConfigurationSectionHandler 成员
InBlock.gif
InBlock.gif 
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif       
public object Create(object parent, object configContext, System.Xml.XmlNode section) dot.gif{
InBlock.gif
InBlock.gif           XmlSerializer Xs 
= new XmlSerializer(sectionObjectType);
InBlock.gif
InBlock.gif           
return Xs.Deserialize(new XmlNodeReader(section));
InBlock.gif
ExpandedSubBlockEnd.gif       }

InBlock.gif
InBlock.gif 
InBlock.gif
ExpandedSubBlockEnd.gif       
#endregion

InBlock.gif
InBlock.gif 
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif       
/**//// <summary>
InBlock.gif
InBlock.gif       
/// 根据配置类得到其配置节的xml形式
InBlock.gif
InBlock.gif       
/// </summary>
InBlock.gif
InBlock.gif       
/// <param name="sectionValue"></param>
InBlock.gif
ExpandedSubBlockEnd.gif       
/// <returns></returns>

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif       
public XmlNode SetSection(object sectionValue)dot.gif{
InBlock.gif
InBlock.gif           
if (sectionValue.GetType().ToString() != sectionObjectType.ToString())
InBlock.gif
InBlock.gif              
throw new ArgumentException("必须为" + sectionObjectType.Name + "类型","sectionValue");
InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif           XmlSerializer Xs 
= new XmlSerializer(sectionObjectType);
InBlock.gif
InBlock.gif           XmlDocument doc 
= new XmlDocument();
InBlock.gif
InBlock.gif           StringWriter sw 
= new StringWriter();
InBlock.gif
InBlock.gif           XmlTextWriter writer 
= new XmlTextWriter(sw);
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif           
trydot.gif{
InBlock.gif
InBlock.gif              Xs.Serialize(writer,sectionValue);
InBlock.gif
InBlock.gif              writer.Flush();
InBlock.gif
InBlock.gif              doc.LoadXml(sw.ToString());
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif           }
finallydot.gif{
InBlock.gif
InBlock.gif              writer.Close();
InBlock.gif
InBlock.gif              sw.Close();
InBlock.gif
ExpandedSubBlockEnd.gif           }

InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif            
return doc.DocumentElement;          
InBlock.gif
ExpandedSubBlockEnd.gif       }

InBlock.gif
ExpandedBlockEnd.gif    }

None.gif
None.gif


 

 

上面HandlerSectionObjectMap.Dictionary里存放着各个SectionHandler与具体的配置设置类的类型的映射。

SetSection方法则是为写配置文件而准备的,其实就是一个XML序列化的过程(而Create则是反序列化过程)。

这样以后,只要在应用里写ConfigurationSettings.GetConfig("Data") as DataCfg就可以把配置文件的配置读出来了。当然最后别忘了在配置文件的开头加上相应的<section>,比如:

<section name="Data"

       type="SectionHandler.DataSectionHandler,Common" />

 

一贴代码这文章就长了好多,今天先到这儿了,写配置文件的问题下篇再述。

 

转载于:https://www.cnblogs.com/lichdr/archive/2007/06/13/781441.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值