应用场景: 设计一个任务调度系统,配置信息以XML行式保存在Tasks.config的配置文件里,该配置里不止一个任务。不同的任务,会有不同配置信息与设定。 解决方案1:使用XPath直接读 优点:1. 直接;2. 灵活(配置可以千变万化) 缺点:1. 不友好,要写一堆的读取XML数据的方法,每次有新的任务时都要重写不同的XML片断;2. 容易出错,很有可能因为写了一个错误的节点属性名称而得不到数据 解决方案2:使用对象序列化成XML文档 缺点:1. 反序列化配置时必须有定义好的类型。 优点:1. 友好,XML里的数据直接反序列化成对象的属性;2. 不容易出错,为什么呢?你肯定要先定义好类型序列化后使用,你别告诉我你是手写XML的; 现在的问题是设计一个方法,解决它的缺点。就算有不同的配置我也能给你反序列化出来。那么抽出相同的部分,这部分不是我们关注的重点了。我们关注的是,如何重现不同的配置XML为实例。因为所有的对象都是继承自object的,那么,我们把扩展部分的类型就设定为object好了。经过测试发现,反序列化后的object是XmlNode[]数组。那我们要做的就是把这个XmlNode[]数组给转换为文本,然后再客户端使用的时候,将文本与定义好的类型进行反序列化。 代码原型: [Serializable, XmlRoot(ElementName = "configuration")] public class XmlConfig { /// <summary> /// 扩展 /// </summary> [XmlElement("extend")] public object Extend { get; set; } /// <summary> /// 获取已设定的扩展类型实例 /// </summary> /// <typeparam name="T">扩展的类型</typeparam> /// <returns>扩展类实例</returns> public T GetExtend<T>() where T:class { return Serializer.XmlDeserializerFormText<T>(ExtendRawXml); } /// <summary> /// Extend扩展的Xml片断 /// </summary> /// <returns></returns> protected string ExtendRawXml { get { var nodes = Extend as XmlNode[]; if (nodes == null || nodes.Length == 0) return "<extend />"; var w = new StringWriter(); XmlWriter writer = new XmlTextWriter(w); writer.WriteStartElement("extend"); foreach (var node in nodes) writer.WriteRaw(node.OuterXml); writer.WriteEndElement(); writer.Close(); return w.ToString(); } } } [Serializable, XmlRoot("extend")] public class MyExtend { public int Id { get; set; } public string Name { get; set; } }
出处:http://atwind.cnblogs.com (责任编辑:admin) |