通过项目获取的新技能,之后写xml配置应该没什么问题,当然xml文件的使用形式多种多样,之后在持续更新。
配置文件编写实践
配置文件一般用xml来写,具体关于xml文件的特性见以下这篇引用的博客,很详细了。
这里我想说一下我学到的设计
xml文件编写
<?xml version="1.0" encoding="utf-8" ?> <CheckMetaDataConfig majorVersion="1" minorVersion="208" //根节点 <DataBases> <DataBase Name="User"> <TableConfigs> <TableConfig Name="dbo.userconfig" ConditionCode="ID,Lable,Name"> //ConditonCode为配置的组合特征,之后需要取出来切割并调用 <Fields> <Field Name="ID" Method="Mapping" Field> //method为我们的比较规则 <Field Name="Lable" Method="Equal"></Field> <Field Name="Name" Method="TenanatReplace"></Field> <Field Name="Application" Method="Equal"></Field> </Fields> </TableConfig> </TableConfigs> </DataBase> </DataBases> </CheckMetaDataConfig>
以上的结构为,一系列的库,一系列的表,一系列的字段,每一级都可以有很多个,每个又可以有自己的属性。为了对应xml,我们需要解析,还要考虑到我们会通过库来调用表,通过表来调用字段
解析xml文件的类的编写
using User.Configuration; using System; using System.Collections.Generic; using System.Xml.Serialization; namespace User { //=============================对应根节点的类========================================== #region 对应根节点的类 /// <summary> /// 类:对应根节点的类 /// </summary> [XmlRoot("CheckMetaDataConfig")] public class CheckMetaDataConfig : BaseConfig<CheckMetaDataConfig> { private static readonly object LockThis = new object(); //获取锁对象 //=============================================属性部分==================================== [XmlArray("DataBases")] [XmlArrayItem("DataBase")] public DataBase[] DataBases { get; set; } //=============================================字段部分==================================== private Dictionary<string, DataBase> _databasedic; //设置字段的字典类 //=============================================方法部分==================================== /// <summary> /// 公有方法:获取指定名称数据库的xml实例 /// </summary> /// <param name="dataBaseName"></param> /// <returns></returns> public DataBase FindDatabase(string dataBaseName) { dataBaseName = dataBaseName.ToLower(); if (_databasedic == null) { InitDatabaseDic(); } return _databasedic != null && _databasedic.ContainsKey(dataBaseName) ? _databasedic[dataBaseName] : null; } /// <summary> /// 私有方法:初始化数据库 /// </summary> private void InitDatabaseDic() { lock (LockThis) { if (_databasedic == null) //如果字典为null,则初始化字典类 { var dic = new Dictionary<String, DataBase>(); //新建一个字典类 foreach (var app in Instance.DataBases) //遍历该数据库 { app.Name = app.Name.ToLower(); //将数据库名全部转为大写 if (string.IsNullOrEmpty(app.Name)) continue; //如果该配置文件里的数据库名字存在,则中止,进入下一个 if (!dic.ContainsKey(app.Name)) //如果字段名字典里不包括该实例里的数据库的名字,添加进去 { dic.Add(app.Name, app); //把数据库名字和数据库实例以字典对的形式添加进去 } } _databasedic = dic; //把处理好的dic赋给字典,全新的字典诞生 } } } } } #endregion 对应根节点的类 //=============================对应数据库节点的类========================================== #region 对应数据库节点的类 /// <summary> /// 类:数据库节点类 /// </summary> public class DataBase { private static readonly object LockThis = new object(); //获取锁对象 //=============================================属性部分==================================== [XmlAttribute("Name")] public string Name { get; set; } [XmlArray("TableConfigs")] [XmlArrayItem("TableConfig")] public TableConfig[] TableConfigs { get; set; } //=============================================字段部分==================================== private Dictionary<string, TableConfig> _tableDic; //=============================================方法部分==================================== /// <summary> ///公有方法: 获取指定名称的数据表 /// </summary> /// <param name="tableName"></param> /// <returns></returns> public TableConfig FindTable(string tableName) { tableName = tableName.ToLower(); if (_tableDic == null) { InitTableDic(); } return _tableDic != null && _tableDic.ContainsKey(tableName) ? _tableDic[tableName] : null; } /// <summary> /// 私有方法:初始化数据表的信息 /// </summary> private void InitTableDic() { lock (LockThis) { if (_tableDic == null) //如果字典为null,则初始化字典类 { var dic = new Dictionary<String, TableConfig>(); //新建一个字典类 foreach (var app in TableConfigs) //遍历该表集合 { app.Name = app.Name.ToLower(); //将数据表名全部转为大写 if (string.IsNullOrEmpty(app.Name)) continue; //如果该配置文件里的数据库名字存在,则中止,进入下一个 if (!dic.ContainsKey(app.Name)) //如果字段名字典里不包括该实例里的数据表的名字,添加进去 { dic.Add(app.Name, app); //把数据表名字和数据表实例以字典对的形式添加进去 } } _tableDic = dic; //把处理好的dic赋给字典,全新的字典诞生 } } } } #endregion 对应数据库节点的类 //=============================对应数据表节点的类========================================== #region 对应数据表节点的类 /// <summary> /// 类:数据表节点类 /// </summary> public class TableConfig { private static readonly object LockThis = new object(); //获取锁对象 //=============================================属性部分==================================== [XmlAttribute("Name")] public string Name { get; set; } [XmlAttribute("ConditionCode")] public string ConditionCode { get; set; } [XmlArray("Fields")] [XmlArrayItem("Field")] public Field[] Fields { get; set; } //=============================================字段部分==================================== private Dictionary<String, string> _conditionCodDic; //=============================================方法部分==================================== /// <summary> /// 公有方法:获取特征码 /// </summary> /// <returns></returns> public Dictionary<String, string> GetConditionCodeDic() { if (_conditionCodDic == null) { InitConditionCodeDic(); } return _conditionCodDic; } /// <summary> /// 私有方法: 初始化特征码 /// </summary> private void InitConditionCodeDic() { lock (LockThis) { if (_conditionCodDic == null) //如果字典为null,则初始化字典类 { var dic = new Dictionary<string, string>(); //新建一个字典类 var strs = ConditionCode.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries); //不保留空元素,获取到特征值字段集合 foreach (var s in strs) { dic.Add(s, null); } _conditionCodDic = dic; //把处理好的dic赋给字典,全新的字典诞生 } } } } #endregion 对应数据表节点的类 //=============================对应字段节点的类========================================== #region 对应字段节点的类 /// <summary> /// 类: 字段类 /// </summary> public class Field { //=============================================属性部分==================================== [XmlAttribute("Name")] public string Name { get; set; } [XmlAttribute("Method")] public string Method { get; set; } } #endregion 对应字段节点的类
以上代码类似InitTableDic用到的初始化方式可以大大减少访问次数,如果存在就不需要再次获取
调用xml文件类
var dataDaseConfig = CheckMetaDataConfig.Instance.FindDatabase(MetaDataBaseName); //获取一个配置文件中数据库节点实例
踩过的坑
1,xml解析类编写的时候,字典类的访问修饰符必须是private:private Dictionary<String, string> _conditionCodDic;
2,xml解析类尽量不要出现子类,要写为同级的
3,注意xml文件名必须和xml解析类必须同名