在项目开发过程中有一些配置信息需要保存,为了便于管理和使用配置信息,我将配置信息保存在一个xml文件中,每一类配置信息作为一个配置节,通过调用WriteConfigSection(object o) 函数将配置信息类 o 中的数据记录到配置文件中。通过调用ReadConfigSection(Type type)返回包含配置信息的对象。
实现思路:
1.定义配置信息类,该类实现一个接口 IEntiry,该接口用于读取配置文件时调用SetPropertyDic函数给对象的变量赋值。
/// <summary>
/// 配置文件必须实现该接口,在SetPropertyDic函数中给各自属性赋值
/// </summary>
public interface IEntiry
{
void SetPropertyDic(Dictionary<object, object> PropertiesDic);
}
2. 定义一个 Attribute,标识配置信息类的配置节属性 ConfigEntityAttribute
/// <summary>
/// 配置信息类属性
/// </summary>
[AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = false)]
public class ConfigEntityAttribute : Attribute
{
private string _configEntityName;
public string ConfigEntityName
{
get
{
return _configEntityName;
}
}
public ConfigEntityAttribute(string configEntityName)
{
this._configEntityName = configEntityName;
}
}
3. 保存配置信息
/// <summary>
/// 创建配置节
/// </summary>
/// <param name="o"></param>
public void WriteConfigSection(object o)
{
Type type = o.GetType();
if (!Attribute.IsDefined(type, typeof(ConfigEntityAttribute)))
{
throw new Exception("传入的配置类没有ConfigEntityAttribute属性");
}
ConfigEntityAttribute attr = Attribute.GetCustomAttribute(type, typeof(ConfigEntityAttribute)) as ConfigEntityAttribute;
string configSectionPath = this._appSectionPath + @"//" + attr.ConfigEntityName;
XmlNode secctionNode = this.GetConfigSectionNode(configSectionPath);
if (secctionNode == null)
{
secctionNode = this._XDoc.CreateElement(attr.ConfigEntityName) as XmlNode;
}
else
{
secctionNode.RemoveAll();
}
FieldInfo[] memberInfoArray = type.GetFields();
foreach (FieldInfo info in memberInfoArray)
{
XmlElement settingNode = this._XDoc.CreateElement("setting");
settingNode.SetAttribute("name", info.Name);
settingNode.SetAttribute("serializeAs", info.FieldType.FullName);
XmlNode valeNode = this._XDoc.CreateElement("Value") as XmlNode;
valeNode.InnerText = info.GetValue(o).ToString();
settingNode.AppendChild(valeNode);
secctionNode.AppendChild(settingNode);
}
XmlNode appNode = this.GetConfigSectionNode(this._appSectionPath);
appNode.AppendChild(secctionNode);
this._XDoc.Save(this._configFilePath);
}
4. 读取配置信息
/// <summary>
/// 读出配置节
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public object ReadConfigSection(Type type)
{
if (!Attribute.IsDefined(type, typeof(ConfigEntityAttribute)))
{
throw new Exception("传入的配置类没有ConfigEntityAttribute属性");
}
ConfigEntityAttribute attr = Attribute.GetCustomAttribute(type, typeof(ConfigEntityAttribute)) as ConfigEntityAttribute;
string configSectionPath = this._appSectionPath + @"//" + attr.ConfigEntityName;
IEntiry iEntiry = Activator.CreateInstance(type) as IEntiry;
Dictionary<object, object> dic = new Dictionary<object, object>();
FieldInfo[] fieldInfoArray = type.GetFields();
XmlNode xNode = (XmlNode)(this._XDoc.SelectNodes(configSectionPath).Item(0));
if (xNode == null)
return null;
foreach (FieldInfo info in fieldInfoArray)
{
try
{
XmlNode xNode2 = xNode.SelectSingleNode(string.Format("setting[@name='{0}']", info.Name));
XmlElement xElement = (XmlElement)xNode2.FirstChild;
dic[info.Name] = xElement.InnerText;
}
catch (Exception ex)
{
dic[info.Name] = null;
}
}
iEntiry.SetPropertyDic(dic); //从这里给传进来的配置信息类的字段赋值。 不知道有什么好的方法????
return iEntiry;
}
使用:
1. 定义配置信息类:
[ConfigEntity("ConfigToolTest.Form1")] //配置信息的标识,要唯一
public class Entity_UserInfo : IEntiry
{
public string 姓名;
public string 性别;
public int 年龄;
public DateTime 生日;
public Entity_UserInfo()
{
}
public Entity_UserInfo(string name, string sex, int age, DateTime birthday)
{
this.姓名 = name;
this.性别 = sex;
this.年龄 = age;
this.生日 = birthday;
}
#region IEntiry 成员
public void SetPropertyDic(Dictionary<object, object> dic) //不知道通过什么方式可以把这个函数省略掉?????
{
try
{
if (dic["姓名"] != null)
this.姓名 = dic["姓名"].ToString();
if (dic["性别"] != null)
this.性别 = dic["性别"].ToString();
if (dic["年龄"] != null)
this.年龄 = Convert.ToInt32(dic["年龄"].ToString());
if (dic["生日"] != null)
this.生日 = DateTime.Parse(dic["生日"].ToString());
}
catch (Exception ex)
{
throw ex;
}
}
private void button_Save_Click(object sender, EventArgs e)
{
Entity_UserInfo userInfo = new Entity_UserInfo(this.textBox_Name.Text, this.textBox_Sex.Text, int.Parse(this.textBox_Age.Text), DateTime.Parse(this.textBox_Birthday.Text));
ConfigHelper configHelper = new ConfigHelper();/Files/zhaobl/ConfigTool.rar
configHelper.WriteConfigSection(userInfo);
}
3. 读取配置信息
private void button_Read_Click(object sender, EventArgs e)
{
ConfigHelper configHelper = new ConfigHelper();
Entity_UserInfo userInfo = configHelper.ReadConfigSection(typeof(Entity_UserInfo)) as Entity_UserInfo;
}
2009-07-27 更正
对于上面红色标注的地方通过反射和泛型可以解决:
/// <summary>
/// 读出配置节
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public T ReadConfigSection<T>() where T : class, new()
{
Type type = typeof(T);
T t = new T();
if (!Attribute.IsDefined(type, typeof(ConfigEntityAttribute)))
{
throw new Exception("传入的配置类没有ConfigEntityAttribute属性");
}
ConfigEntityAttribute attr = Attribute.GetCustomAttribute(type, typeof(ConfigEntityAttribute)) as ConfigEntityAttribute;
string configSectionPath = this._appSectionPath + @"//" + attr.ConfigEntityName;
FieldInfo[] fieldInfoArray = type.GetFields();
XmlNode xNode = (XmlNode)(this._XDoc.SelectNodes(configSectionPath).Item(0));
if (xNode == null)
return null;
foreach (FieldInfo info in fieldInfoArray)
{
try
{
XmlNode xNode2 = xNode.SelectSingleNode(string.Format("setting[@name='{0}']", info.Name));
XmlElement xElement = (XmlElement)xNode2.FirstChild;
type.InvokeMember(info.Name, BindingFlags.SetField, null, t, new object[] { xElement.InnerText });
}
catch (Exception ex)
{
}
}
return t;
}
浙公网安备 33010602011771号