private void ReadObject(XElement ele, ConfigAttributeTypes configAttributeTypes, PropertyInfo propertyInfo, ref object ownerObj) { object value = propertyInfo.GetValue(ownerObj, null); if (value == null) { if (!propertyInfo.CanWrite) { throw new ArgumentException($"属性{propertyInfo.DeclaringType.FullName}.{propertyInfo.Name}不支持set操作"); } value = Activator.CreateInstance(propertyInfo.PropertyType); if (!propertyInfo.PropertyType.IsValueType) { propertyInfo.SetValue(ownerObj, value, null); } } PropertyInfo[] complexProInfoArr = this.GetTypePropertyInfos(propertyInfo.PropertyType); this.ReadConfigToXml(ele, complexProInfoArr, ref value, configAttributeTypes); if (propertyInfo.PropertyType.IsValueType) { propertyInfo.SetValue(ownerObj, value, null); } }
private void ReadIList(IList list, Type eleType, XElement[] eleEleArr, ConfigAttributeTypes configAttributeTypes) { ConfigDataType configDataType = this.GetDataType(eleType); string value, eleName = null; object obj; switch (configDataType) { case ConfigDataType.IDictionary: foreach (var eleEle in eleEleArr) { obj = Activator.CreateInstance(eleType); this.ReadIDictionary((IDictionary)obj, eleEle.Elements(eleName).ToArray(), eleType, configAttributeTypes); list.Add(obj); } break; case ConfigDataType.IList: var itemType2 = this.GetIListElementType(eleType); eleName = this.GetIListElementName(itemType2); XElement[] eleEleArr2; foreach (var eleEle in eleEleArr) { eleEleArr2 = eleEle.Elements(eleName).ToArray(); obj = this.CreateIList(eleType, eleEleArr2.Length); this.ReadIList((IList)obj, itemType2, eleEleArr2, configAttributeTypes); list.Add(obj); } break; case ConfigDataType.Object: PropertyInfo[] objPropertyInfoArr = this.GetTypePropertyInfos(eleType); int index = 0; foreach (var eleEle in eleEleArr) { obj = Activator.CreateInstance(eleType); this.ReadConfigToXml(eleEle, objPropertyInfoArr, ref obj, configAttributeTypes); if (list is Array) { list[index++] = obj; } else { list.Add(obj); } } break; case ConfigDataType.Basic: foreach (var eleEle in eleEleArr) { value = XmlEx.GetXElementAttributeValue(eleEle, _VALUE, true); list.Add(this.StringToObject(value, eleType)); } break; default: throw new NotImplementedException(configDataType.ToString()); } }
private void WriteObject(XElement ownerEle, ConfigAttributeTypes configAttributeTypes, object propertyValue, PropertyInfo propertyInfo) { string complexEleName = this.GetConfigItemName(propertyInfo); XElement complexEle = new XElement(complexEleName); ownerEle.Add(complexEle); if (propertyValue != null) { PropertyInfo[] complexPropertyInfoArr = this.GetTypePropertyInfos(propertyInfo.PropertyType); this.WriteConfigToXml(complexEle, complexPropertyInfoArr, propertyValue, configAttributeTypes); } }
/// <summary> /// 从xml配置中读取配置到指定的配置对象中 /// </summary> /// <param name="xdoc">xml配置</param> /// <param name="config">指定的配置对象</param> public void ReadConfigFromXDocument(XDocument xdoc, ref object config) { ConfigAttributeTypes configAttributeTypes = new ConfigAttributeTypes(); Type configType = config.GetType(); ConfigRootAttribute configRootAttribute = ConfigRootAttribute.GetRootConfigRootAttribute(configType, configAttributeTypes); XElement rootEle = xdoc.XPathSelectElement(configRootAttribute.GetName(configType)); if (rootEle == null) { return; } PropertyInfo[] propertyInfoArr = this.GetTypePropertyInfos(configType); this.ReadConfigToXml(rootEle, propertyInfoArr, ref config, configAttributeTypes); }
private void WriteObject(XElement ownerEle, ConfigAttributeTypes configAttributeTypes, ConfigAttribute attri, object propertyValue, PropertyInfo propertyInfo) { if (!attri.AllowNullValueElement && propertyValue == null) { return; } XElement complexEle = new XElement(attri.GetName(propertyInfo)); this.AddDes(complexEle, attri.Des); ownerEle.Add(complexEle); if (propertyValue != null) { PropertyInfo[] complexPropertyInfoArr = this.GetTypePropertyInfos(propertyInfo.PropertyType); this.WriteConfigToXml(complexEle, complexPropertyInfoArr, propertyValue, configAttributeTypes); } }
/// <summary> /// 写配置到XDocument /// </summary> /// <param name="config">配置对象</param> /// <returns>配置XDocument</returns> public XDocument WriteConfigToXDocument(object config) { if (config == null) { throw new ArgumentNullException(nameof(config)); } ConfigAttributeTypes configAttributeTypes = new ConfigAttributeTypes(); XDocument xdoc = new XDocument(); Type configType = config.GetType(); ConfigRootAttribute configRootAttribute = ConfigRootAttribute.GetRootConfigRootAttribute(configType, configAttributeTypes); XElement rootEle = new XElement(configRootAttribute.GetName(configType)); this.AddDes(rootEle, configRootAttribute.Des); PropertyInfo[] propertyInfoArr = this.GetTypePropertyInfos(configType); this.WriteConfigToXml(rootEle, propertyInfoArr, config, configAttributeTypes); xdoc.Add(rootEle); return(xdoc); }
private void ReadIList(ref object ownerObj, PropertyInfo propertyInfo, XElement[] eleEleArr, ConfigAttributeTypes configAttributeTypes) { //非字典集合类型 var list = (IList)propertyInfo.GetValue(ownerObj, null); if (list == null) { if (!propertyInfo.CanWrite) { throw new ArgumentException($"属性{propertyInfo.DeclaringType.FullName}.{propertyInfo.Name}不支持set操作"); } list = this.CreateIList(propertyInfo.PropertyType, eleEleArr.Length); propertyInfo.SetValue(ownerObj, list, null); } Type eleType = this.GetIListElementType(propertyInfo.PropertyType); this.ReadIList(list, eleType, eleEleArr, configAttributeTypes); }
private void ReadIDictionary(IDictionary dic, XElement[] eleEleArr, Type eleType, ConfigAttributeTypes configAttributeTypes) { XElement keyEle, valueEle; string keyStr, valueStr; object key, value = null; Type[] argsTypeArr = eleType.GetGenericArguments(); ConfigDataType configDataType = this.GetDataType(argsTypeArr[1]); string name2 = null, eleName2 = null, eleName3 = null; Type eleType2 = null; PropertyInfo[] objPropertyInfoArr = null; XElement[] eleEleArr2 = null; foreach (var childEle in eleEleArr) { keyEle = childEle.Element(_KEY); keyStr = XmlEx.GetXElementAttributeValue(keyEle, _VALUE, false); key = this.StringToObject(keyStr, argsTypeArr[0]); valueEle = childEle.Element(_VALUE); switch (configDataType) { case ConfigDataType.Basic: valueStr = XmlEx.GetXElementAttributeValue(valueEle, _VALUE, true); if (valueStr == null) { value = null; } else { value = this.StringToObject(valueStr, argsTypeArr[1]); } break; case ConfigDataType.IDictionary: if (name2 == null) { name2 = this.GetIListElementName(argsTypeArr[1]); } if (eleName2 == null) { eleName2 = this.GetIDictionaryElementName(null); } value = Activator.CreateInstance(argsTypeArr[1]); this.ReadIDictionary((IDictionary)value, valueEle.XPathSelectElements($"{name2}/{eleName2}").ToArray(), argsTypeArr[1], configAttributeTypes); break; case ConfigDataType.IList: if (eleType2 == null) { eleType2 = this.GetIListElementType(argsTypeArr[1]); } if (eleName2 == null) { eleName2 = this.GetIListElementName(argsTypeArr[1]); } if (eleName3 == null) { eleName3 = this.GetIListElementName(eleType2); } eleEleArr2 = valueEle.XPathSelectElements($"{eleName2}/{eleName3}").ToArray(); value = this.CreateIList(argsTypeArr[1], eleEleArr2.Length); this.ReadIList((IList)value, eleType2, eleEleArr2, configAttributeTypes); break; case ConfigDataType.Object: if (objPropertyInfoArr == null) { objPropertyInfoArr = this.GetTypePropertyInfos(argsTypeArr[1]); } if (eleName2 == null) { eleName2 = this.GetIListElementName(argsTypeArr[1]); } value = Activator.CreateInstance(argsTypeArr[1]); this.ReadConfigToXml(valueEle.Element(eleName2), objPropertyInfoArr, ref value, configAttributeTypes); break; default: throw new NotSupportedException(configDataType.ToString()); } dic[key] = value; } }
private void ReadIDictionary(ref object ownerObj, XElement[] eleEleArr, PropertyInfo propertyInfo, ConfigAttributeTypes configAttributeTypes) { var dic = (IDictionary)propertyInfo.GetValue(ownerObj, null); if (dic == null) { if (!propertyInfo.CanWrite) { throw new ArgumentException($"属性{propertyInfo.DeclaringType.FullName}.{propertyInfo.Name}不支持set操作"); } dic = ActivatorEx.CreateInstance <IDictionary>(propertyInfo.PropertyType); propertyInfo.SetValue(ownerObj, dic, null); } this.ReadIDictionary(dic, eleEleArr, propertyInfo.PropertyType, configAttributeTypes); }
private void ReadConfigToXml(XElement ownerEle, PropertyInfo[] propertyInfoArr, ref object ownerObj, ConfigAttributeTypes configAttributeTypes) { ConfigAttribute attri; Dictionary <string, XElement> eleDic = this.GetElementsDic(ownerEle); ConfigDataType configDataType; string name, eleName; object customerValue = null; XElement ele; Type eleType; foreach (var propertyInfo in propertyInfoArr) { attri = propertyInfo.GetCustomAttribute(configAttributeTypes.IgnoreAttributeType, false) as ConfigAttribute; if (attri != null) { //忽略该属性 continue; } attri = propertyInfo.GetCustomAttribute(configAttributeTypes.ConfigCommentAttributeType, false) as ConfigCommentAttribute; if (attri != null) { //注释 continue; } configDataType = this.GetDataType(propertyInfo.PropertyType); attri = propertyInfo.GetCustomAttribute(configAttributeTypes.CustomerAttributeType, false) as ConfigAttribute; if (attri != null) { var configItemCustomerAttribute = (ConfigCustomerAttribute)attri; customerValue = configItemCustomerAttribute.CustomerConfig.Read(propertyInfo, ownerEle, configItemCustomerAttribute); propertyInfo.SetValue(ownerObj, customerValue, null); continue; } attri = propertyInfo.GetCustomAttribute(configAttributeTypes.CollectionAttributeType, false) as ConfigAttribute; if (attri != null) { var collectionAtt = (ConfigCollectionAttribute)attri; name = collectionAtt.GetName(propertyInfo); if (!eleDic.TryGetValue(name, out ele)) { //属性对应的配置项不存在,忽略 continue; } if (configDataType == ConfigDataType.IDictionary) { eleName = this.GetIDictionaryElementName(collectionAtt.ElementName); this.ReadIDictionary(ref ownerObj, ele.Elements(eleName).ToArray(), propertyInfo, configAttributeTypes); } else { eleType = this.GetIListElementType(propertyInfo.PropertyType); eleName = collectionAtt.GetElementName(eleType); this.ReadIList(ref ownerObj, propertyInfo, ele.Elements(eleName).ToArray(), configAttributeTypes); } continue; } attri = propertyInfo.GetCustomAttribute(configAttributeTypes.ObjectAttributeType, false) as ConfigAttribute; if (attri != null) { //复合对象 name = attri.GetName(propertyInfo); if (!eleDic.TryGetValue(name, out ele)) { //属性对应的配置项不存在,忽略 continue; } this.ReadObject(ele, configAttributeTypes, propertyInfo, ref ownerObj); continue; } attri = propertyInfo.GetCustomAttribute(configAttributeTypes.ItemAttributeType, false) as ConfigAttribute; if (attri != null) { //基元项 name = attri.GetName(propertyInfo); if (!eleDic.TryGetValue(name, out ele)) { //属性对应的配置项不存在,忽略 continue; } this.ReadItem(ele, ((ConfigItemAttribute)attri).Converter, propertyInfo, ownerObj); continue; } //未标记项==================================================================================================== switch (configDataType) { case ConfigDataType.IDictionary: name = this.GetIDictionaryName(null, propertyInfo); if (!eleDic.TryGetValue(name, out ele)) { //属性对应的配置项不存在,忽略 continue; } eleName = this.GetIDictionaryElementName(null); this.ReadIDictionary(ref ownerObj, ele.Elements(eleName).ToArray(), propertyInfo, configAttributeTypes); break; case ConfigDataType.IList: eleName = this.GetConfigItemName(propertyInfo); if (!eleDic.TryGetValue(eleName, out ele)) { //属性对应的配置项不存在,忽略 continue; } eleType = this.GetIListElementType(propertyInfo.PropertyType); eleName = this.GetIListElementName(eleType); this.ReadIList(ref ownerObj, propertyInfo, ele.Elements(eleName).ToArray(), configAttributeTypes); break; case ConfigDataType.Object: string complexEleName = this.GetConfigItemName(propertyInfo); if (!eleDic.TryGetValue(complexEleName, out ele)) { //属性对应的配置项不存在,忽略 continue; } this.ReadObject(ele, configAttributeTypes, propertyInfo, ref ownerObj); break; case ConfigDataType.Basic: eleName = this.GetConfigItemName(propertyInfo); if (!eleDic.TryGetValue(eleName, out ele)) { //属性对应的配置项不存在,忽略 continue; } this.ReadItem(ele, null, propertyInfo, ownerObj); break; default: throw new NotImplementedException(configDataType.ToString()); } } }
private void WriteIDictionary(XElement ownerEle, IDictionary dic, Type dicType, string name, string eleName, string des, ConfigAttributeTypes configAttributeTypes) { if (dic == null || dic.Count == 0) { return; } XElement dicEle = new XElement(name); this.AddDes(dicEle, des); ownerEle.Add(dicEle); object value; Type[] argsTypeArr = dicType.GetGenericArguments(); ConfigDataType keyDataType = this.GetDataType(argsTypeArr[0]); ConfigDataType valueDataType = this.GetDataType(argsTypeArr[1]); PropertyInfo[] objPropertyInfoArr = null; string name2 = null, eleName2 = null, eleName3 = null; Type eleType = null; foreach (var key in dic.Keys) { XElement eleEle = new XElement(eleName); dicEle.Add(eleEle); //key XElement keyEle = new XElement(_KEY); switch (keyDataType) { case ConfigDataType.Basic: keyEle.Add(new XAttribute(_VALUE, key.ToString())); break; case ConfigDataType.IDictionary: case ConfigDataType.IList: case ConfigDataType.Object: default: throw new NotSupportedException($"字典集合的key只能为基础类型数据,类型{keyDataType.ToString()}无效"); } eleEle.Add(keyEle); value = dic[key]; XElement valueEle = new XElement(_VALUE); switch (valueDataType) { case ConfigDataType.Basic: if (value != null) { valueEle.Add(new XAttribute(_VALUE, value.ToString())); } break; case ConfigDataType.IDictionary: if (name2 == null) { name2 = this.GetIListElementName(argsTypeArr[1]); } if (eleName2 == null) { eleName2 = this.GetIDictionaryElementName(null); } this.WriteIDictionary(valueEle, (IDictionary)value, argsTypeArr[1], name2, eleName2, null, configAttributeTypes); break; case ConfigDataType.IList: if (eleType == null) { eleType = this.GetIListElementType(argsTypeArr[1]); } if (eleName2 == null) { eleName2 = this.GetIListElementName(argsTypeArr[1]); } if (eleName3 == null) { eleName3 = this.GetIListElementName(eleType); } XElement listChildEle = new XElement(eleName2); this.WriteIList(eleName3, listChildEle, (IList)value, eleType, configAttributeTypes); valueEle.Add(listChildEle); break; case ConfigDataType.Object: if (objPropertyInfoArr == null) { objPropertyInfoArr = this.GetTypePropertyInfos(argsTypeArr[1]); } if (eleName2 == null) { eleName2 = this.GetIListElementName(argsTypeArr[1]); } XElement childEle = new XElement(eleName2); this.WriteConfigToXml(childEle, objPropertyInfoArr, value, configAttributeTypes); valueEle.Add(childEle); break; default: throw new NotSupportedException(valueDataType.ToString()); } eleEle.Add(valueEle); } }
private void WriteIList(string name, XElement collectionEle, IList list, Type eleType, ConfigAttributeTypes configAttributeTypes) { if (list == null || list.Count == 0) { return; } string eleName = this.GetIListElementName(eleType), eleName2 = null; ConfigDataType configDataType = this.GetDataType(eleType); switch (configDataType) { case ConfigDataType.IDictionary: eleName2 = this.GetIDictionaryElementName(null); foreach (var item in list) { this.WriteIDictionary(collectionEle, (IDictionary)item, eleType, eleName, eleName2, null, configAttributeTypes); } break; case ConfigDataType.IList: var itemType2 = this.GetIListElementType(eleType); eleName = this.GetIListElementName(itemType2); foreach (var item in list) { XElement itemEle = new XElement(name); collectionEle.Add(itemEle); this.WriteIList(eleName, itemEle, (IList)item, itemType2, configAttributeTypes); } break; case ConfigDataType.Object: PropertyInfo[] objPropertyInfoArr = this.GetTypePropertyInfos(eleType); foreach (var item in list) { if (item == null) { continue; } XElement childEle = new XElement(name); this.WriteConfigToXml(childEle, objPropertyInfoArr, item, configAttributeTypes); collectionEle.Add(childEle); } break; case ConfigDataType.Basic: foreach (var item in list) { this.WriteItem(collectionEle, name, item, null); } break; default: throw new NotImplementedException(configDataType.ToString()); } }
private void WriteIList(string name, string eleName, string des, XElement ownerEle, IList list, Type listType, ConfigAttributeTypes configAttributeTypes) { XElement collectionEle = new XElement(name); this.AddDes(collectionEle, des); ownerEle.Add(collectionEle); var eleType = this.GetIListElementType(listType); this.WriteIList(eleName, collectionEle, list, eleType, configAttributeTypes); }
private void WriteConfigToXml(XElement ownerEle, PropertyInfo[] ownerObjPropertyInfoArr, object ownerObj, ConfigAttributeTypes configAttributeTypes) { if (ownerObj == null) { return; } ConfigAttribute attri; object propertyValue; string name, eleName, comment; Type eleType; ConfigDataType configDataType; foreach (var propertyInfo in ownerObjPropertyInfoArr) { attri = propertyInfo.GetCustomAttribute(configAttributeTypes.IgnoreAttributeType, false) as ConfigAttribute; if (attri != null) { //忽略该属性 continue; } propertyValue = propertyInfo.GetValue(ownerObj, null); attri = propertyInfo.GetCustomAttribute(configAttributeTypes.ConfigCommentAttributeType, false) as ConfigCommentAttribute; if (attri != null) { //注释 if (propertyValue != null) { if (propertyValue is string) { comment = (string)propertyValue; } else { comment = propertyValue.ToString(); } ownerEle.Add(new XComment(comment)); } continue; } configDataType = this.GetDataType(propertyInfo.PropertyType); attri = propertyInfo.GetCustomAttribute(configAttributeTypes.CustomerAttributeType, false) as ConfigAttribute; if (attri != null) { //自定义 var configItemCustomerAttribute = (ConfigCustomerAttribute)attri; configItemCustomerAttribute.CustomerConfig.Write(propertyInfo, propertyValue, ownerEle, configItemCustomerAttribute); continue; } attri = propertyInfo.GetCustomAttribute(configAttributeTypes.CollectionAttributeType, false) as ConfigAttribute; if (attri != null) { //集合 var collectionAtt = (ConfigCollectionAttribute)attri; name = collectionAtt.GetName(propertyInfo); if (configDataType == ConfigDataType.IDictionary) { eleName = this.GetIDictionaryElementName(collectionAtt.ElementName); this.WriteIDictionary(ownerEle, (IDictionary)propertyValue, propertyInfo.PropertyType, name, eleName, collectionAtt.Des, configAttributeTypes); } else if (configDataType == ConfigDataType.IList) { if (collectionAtt != null && propertyValue == null && !collectionAtt.AllowNullValueElement) { continue; } eleType = this.GetIListElementType(propertyInfo.PropertyType); eleName = collectionAtt.GetElementName(eleType); this.WriteIList(name, eleName, collectionAtt.Des, ownerEle, (IList)propertyValue, propertyInfo.PropertyType, configAttributeTypes); } else { throw new NotImplementedException(configDataType.ToString()); } continue; } attri = propertyInfo.GetCustomAttribute(configAttributeTypes.ObjectAttributeType, false) as ConfigAttribute; if (attri != null) { //复合对象 this.WriteObject(ownerEle, configAttributeTypes, attri, propertyValue, propertyInfo); continue; } attri = propertyInfo.GetCustomAttribute(configAttributeTypes.ItemAttributeType, false) as ConfigAttribute; if (attri != null) { //基元项 this.WriteItem(ownerEle, (ConfigItemAttribute)attri, propertyValue, propertyInfo); continue; } //未标记项==================================================================================================== switch (configDataType) { case ConfigDataType.IDictionary: name = this.GetIDictionaryName(null, propertyInfo); eleName = this.GetIDictionaryElementName(null); this.WriteIDictionary(ownerEle, (IDictionary)propertyValue, propertyInfo.PropertyType, name, eleName, null, configAttributeTypes); break; case ConfigDataType.IList: name = this.GetConfigItemName(propertyInfo); eleType = this.GetIListElementType(propertyInfo.PropertyType); eleName = this.GetIListElementName(eleType); this.WriteIList(name, eleName, null, ownerEle, (IList)propertyValue, propertyInfo.PropertyType, configAttributeTypes); break; case ConfigDataType.Object: this.WriteObject(ownerEle, configAttributeTypes, propertyValue, propertyInfo); break; case ConfigDataType.Basic: this.WriteItem(ownerEle, propertyValue, propertyInfo); break; default: throw new NotImplementedException(configDataType.ToString()); } } }
internal static ConfigRootAttribute GetRootConfigRootAttribute(Type configType, ConfigAttributeTypes configAttributeTypes) { ConfigRootAttribute configAttribute; Attribute attri = configType.GetCustomAttribute(configAttributeTypes.RootAttributeType, false); if (attri == null) { //未标记特性,创建默认值 configAttribute = new ConfigRootAttribute(configType.Name, null, true); } else { configAttribute = (ConfigRootAttribute)attri; } return(configAttribute); }