/// <summary> /// Формирование ноды из свойства простого типа /// </summary> /// <param name="descriptor">Вычеслитель ключей</param> /// <param name="property">Свойство</param> /// <param name="val">зачение</param> /// <param name="parrent">родительская нода</param> /// <param name="typeItem">Тип значения</param> /// <param name="repairId">Id проверки</param> /// <returns></returns> private static Node SimpleToNode(IItemKeyFactory descriptor, PropertyInfo property, object val, Node parrent, Type typeItem, long repairId) { var type = GetTypeValue(typeItem); //if (type == DbType.DateTime) // val = ((DateTime) val).ToBinary(); var res = typeItem.IsEnum ? (int)val : val; return(new Node() { Name = descriptor.GetKey(property), Val = res, Parrent = parrent, TypeVal = (int)type, RepairId = repairId, }); }
/// <summary> /// Convert /// </summary> /// <param name="root"></param> /// <param name="res"></param> /// <param name="targetType"></param> /// <param name="descriptor"></param> /// <returns></returns> public static bool TryParse(Node root, out object res, Type targetType, IItemKeyFactory descriptor) { try { object oldRes = null; if (root.Val == null && root.RefValue != null) { oldRes = root.RefValue.Target; } else if (root.Val != null) { oldRes = root.Val; } if (oldRes != null && targetType.IsAssignableFrom(oldRes.GetType())) { res = oldRes; return(true); } res = targetType.Assembly.CreateInstance(targetType.FullName); var properties = targetType.GetProperties().Where(p => p.CanRead && p.CanWrite); foreach (var property in properties) { var key = descriptor.GetKey(property); var item = root.Childs.FirstOrDefault(node => node.Name == key); if (item == null) { continue; } if (IsSimple(property.PropertyType)) {// разбор простых типов var sVal = GetSimpleValue(item); var sType = property.PropertyType; if (sType.IsEnum) { if (sType.IsEnumDefined(sVal)) { property.SetValue(res, Enum.ToObject(sType, sVal), null); } } else { property.SetValue(res, sVal, null); } continue; } if (IsList(property.PropertyType)) {// разбор коллекции var propNodes = root.Childs.Where(node => node.Name == key); var typeItem = property.PropertyType.GetGenericArguments()[0]; var listType = typeof(List <>).MakeGenericType(typeItem); var paramListValue = (IList)Activator.CreateInstance(listType); foreach (var propNode in propNodes) { if (IsSimple(typeItem)) { var sVal = GetSimpleValue(propNode); if (typeItem.IsEnum) { if (typeItem.IsEnumDefined(sVal)) { paramListValue.Add(Enum.ToObject(typeItem, sVal)); } } else { paramListValue.Add(sVal); //наполнение коллекции простых типов } } else { object itemElement; if (!TryParse(propNode, out itemElement, typeItem, descriptor)) { continue; } paramListValue.Add(itemElement); //наполнение коллекции сложных типов } } property.SetValue(res, paramListValue, null); continue; } object itemTarget; // разбор сложного типа if (!TryParse(item, out itemTarget, property.PropertyType, descriptor)) { continue; } property.SetValue(res, itemTarget, null); } } catch (Exception ex) { Debug.WriteLine(ex.ToString()); res = null; return(false); } return(true); }
/// <summary> /// Convert to tree /// </summary> /// <param name="item">source</param> /// <param name="root">root Node</param> /// <param name="descriptor"></param> /// <param name="parentId"></param> /// <returns></returns> public static Node Convert(object item, Node root, IItemKeyFactory descriptor, long parentId) { Node node = root; var itemType = item.GetType(); if (IsSimple(itemType)) { var sVal = itemType.IsEnum ? (int)item : item; node.Val = sVal; return(node); } else { root.RefValue = new WeakReference(item); } var properties = itemType.GetProperties().Where(p => p.CanRead && p.CanWrite); foreach (var property in properties) { var propValue = property.GetValue(item, null); if (IsSimple(property.PropertyType)) { // Add simple type element node.Childs.Add(SimpleToNode(descriptor, property, propValue, node, property.PropertyType, parentId)); continue; } if (IsList(property.PropertyType)) { // Add collection IList propItems = propValue as IList; var typeItem = property.PropertyType.GetGenericArguments()[0]; if (IsSimple(typeItem)) { foreach (var subItem in propItems) {// Add simple type element collection node.Childs.Add(SimpleToNode(descriptor, property, subItem, node, typeItem, parentId)); } } else { foreach (var subItem in propItems) { // Add constructed type element collection var itemNode = new Node() { Name = descriptor.GetKey(property), Parrent = node, RepairId = parentId }; Convert(subItem, itemNode, descriptor, parentId); node.Childs.Add(itemNode); } } continue; } // Add constructed type element if (propValue == null) { continue; } var newNode = new Node() { Name = descriptor.GetKey(property), Parrent = node, RepairId = parentId }; Convert(propValue, newNode, descriptor, parentId); node.Childs.Add(newNode); } return(node); }