public static ReferenceNode BuildReferenceTree(object graph) { var queue = new Queue <ReferenceNode>(); var rootNode = new ReferenceNode(graph); var referenceMapping = new Dictionary <object, ReferenceNode>(new ReferenceEqualsComparer <object>()); queue.Enqueue(rootNode); referenceMapping.Add(graph, rootNode); while (queue.Count > 0) { var activeNode = queue.Dequeue(); var values = new List <Utils.Tuple <object, string> >(); foreach (var propertyInfo in GetAllProperties(activeNode.Object)) { object value = null; try { if (propertyInfo.GetIndexParameters().Length == 0) { value = propertyInfo.GetValue(activeNode.Object, null); } } catch (Exception) { } if (!ShouldInvestigateValueFurther(value)) { continue; } values.Add(new Utils.Tuple <object, string>(value, propertyInfo.Name)); } if (activeNode.Object is IEnumerable) { var enumerable = activeNode.Object as IEnumerable; var index = 0; foreach (var subobject in enumerable) { if (!ShouldInvestigateValueFurther(subobject)) { break; //not the kind of list we want to enumerate.. (right?) } values.Add(new Utils.Tuple <object, string>(subobject, string.Format("[{0}]", index))); index++; } } foreach (var valueTuple in values) { var value = valueTuple.First; var valueAsCollection = value as ICollection; var valueAsGeometry = value as IGeometry; if (value == null || //skip null values (valueAsCollection != null && valueAsCollection.Count == 0) || //skip empty collections valueAsGeometry != null) //skip geometry && datetime { continue; } ReferenceNode referenceNode; var addPath = false; if (referenceMapping.ContainsKey(value)) { referenceNode = referenceMapping[value]; } else { referenceNode = new ReferenceNode(value); referenceMapping.Add(value, referenceNode); queue.Enqueue(referenceNode); addPath = true; } var link = new ReferenceLink(activeNode, referenceNode, valueTuple.Second); activeNode.Links.Add(link); if (addPath) { var path = new List <ReferenceLink>(activeNode.Path) { link }; referenceNode.Path = path; } } } return(rootNode); }
private static ReferenceNode BuildReferenceTree(object graph) { var queue = new Queue <ReferenceNode>(); var rootNode = new ReferenceNode(graph); var referenceMapping = new Dictionary <object, ReferenceNode>(new ReferenceEqualsComparer <object>()); queue.Enqueue(rootNode); referenceMapping.Add(graph, rootNode); while (queue.Count > 0) { var activeNode = queue.Dequeue(); var values = new List <Utils.Tuple <object, string> >(); foreach (var propertyInfo in GetAllProperties(activeNode.Object)) { object value = null; try { if (propertyInfo.GetIndexParameters().Length == 0) { value = propertyInfo.GetValue(activeNode.Object, null); } } catch (Exception) { } if (value == null || value.GetType().IsValueType) { continue; } values.Add(new Utils.Tuple <object, string>(value, propertyInfo.Name)); } if (activeNode.Object is IEnumerable) { var enumerable = activeNode.Object as IEnumerable; foreach (var subobject in enumerable) { if (subobject == null || subobject.GetType().IsValueType) { break; } values.Add(new Utils.Tuple <object, string>(subobject, "[?]")); } } foreach (var valueTuple in values) { var value = valueTuple.First; var valueAsCollection = value as ICollection; var valueAsGeometry = value as IGeometry; if (value == null || //skip null values (valueAsCollection != null && valueAsCollection.Count == 0) || //skip empty collections valueAsGeometry != null) //skip geometry && datetime { continue; } ReferenceNode referenceNode = null; bool addPath = false; if (referenceMapping.ContainsKey(value)) { referenceNode = referenceMapping[value]; } else { referenceNode = new ReferenceNode(value); referenceMapping.Add(value, referenceNode); queue.Enqueue(referenceNode); addPath = true; } var link = new ReferenceLink(activeNode, referenceNode, valueTuple.Second); activeNode.Links.Add(link); if (addPath) { var path = new List <ReferenceLink>(activeNode.Path); path.Add(link); referenceNode.Path = path; } } } return(rootNode); }