コード例 #1
0
 public static IGraphNode Create(object data, IXamlObjectGraphBuilder builder)
 {
     return(ObjectGraphWalker.BuildGraph("Root", data, data.GetType(), null, builder));
 }
コード例 #2
0
        private static IGraphNode BuildGraph(string name, object data, Type type, IGraphNode parent, IXamlObjectGraphBuilder builder)
        {
            Queue <IGraphNode>           pendingQueue   = new Queue <IGraphNode>();
            Dictionary <int, IGraphNode> visitedObjects = new Dictionary <int, IGraphNode>();

            IGraphNode root = ObjectGraphWalker.BuildNodeHelper(name, data, type, parent, null, builder, false);

            pendingQueue.Enqueue(root);

            while (pendingQueue.Count != 0)
            {
                IGraphNode node     = pendingQueue.Dequeue();
                object     nodeData = ObjectGraphWalker.GetObjectData(node);
                Type       nodeType = ObjectGraphWalker.GetObjectType(node);

                // clear the properties so they don't potentially get serialized
                ObjectGraphWalker.ClearObjectData(node);
                ObjectGraphWalker.ClearObjectType(node);

                if (nodeData == null || nodeType.IsPrimitive == true ||
                    nodeType == typeof(System.String))
                {
                    // we have reached a leaf node //
                    continue;
                }

                if (visitedObjects.Keys.Contains(nodeData.GetHashCode()))
                {
                    // Caused by a cycle - alredy seen this node //
                    IGraphNode builtNode = visitedObjects[nodeData.GetHashCode()];

                    foreach (IGraphNode newChild in builder.BuildVisitedNode(builtNode, node))
                    {
                        node.Children.Add(newChild);
                    }
                    //node.Children.Add(visitedObjects[nodeData.GetHashCode()]);
                    continue;
                }
                // ok the type is a complex type - query all properties //
                // create children for clr properties //
                PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(nodeData);

                foreach (PropertyDescriptor property in properties)
                {
                    if (ObjectGraphWalker.IsReadablePropertyDescriptor(property))
                    {
                        object value = null;
                        try
                        {
                            value = property.GetValue(nodeData);
                        }
                        catch (Exception ex) // jasonv - approved; convert exception into value
                        {
                            value = ex;
                        }

                        IGraphNode childNode = ObjectGraphWalker.BuildNodeHelper(property.Name, value, property.PropertyType, node, property.Name, builder, property.IsReadOnly);

                        if (childNode == null)
                        {
                            continue;
                        }

                        IGraphNode actualChild = childNode;
                        while (actualChild.Parent != node)
                        {
                            actualChild = actualChild.Parent;
                            if (actualChild == null)
                            {
                                throw new InvalidOperationException("Node returned from BuildNode has invalid parent.");
                            }
                        }

                        node.Children.Add(actualChild);
                        pendingQueue.Enqueue(childNode);
                    }
                }

                // IEnumerable support //
                int         count          = 0;
                IEnumerable enumerableData = nodeData as IEnumerable;
                if (enumerableData != null && nodeData.GetType() != typeof(System.String))
                {
                    IGraphNode collectionParent = builder.BuildCollectionWrapperNode(node);

                    if (collectionParent != null)
                    {
                        node.Children.Add(collectionParent);
                    }
                    else
                    {
                        collectionParent = node;
                    }

                    IEnumerator enumerator = enumerableData.GetEnumerator();
                    while (enumerator.MoveNext())
                    {
                        IGraphNode childNode = ObjectGraphWalker.BuildNodeHelper("IEnumerable" + count++, enumerator.Current, enumerator.Current == null ? typeof(object) : enumerator.Current.GetType(), collectionParent, null, builder, false);
                        if (childNode == null)
                        {
                            continue;
                        }
                        collectionParent.Children.Add(childNode);
                        pendingQueue.Enqueue(childNode);
                    }
                }

                visitedObjects.Add(nodeData.GetHashCode(), node);
            }

            return(root);
        }
コード例 #3
0
        private static IGraphNode BuildNodeHelper(string name, object data, Type type, IGraphNode parent, string propertyName, IXamlObjectGraphBuilder builder, bool isReadOnly)
        {
            IGraphNode node = builder.BuildNode(name, data, type, parent, propertyName, isReadOnly);

            if (node == null)
            {
                return(node);
            }
            ObjectGraphWalker.SetObjectData(node, data);
            ObjectGraphWalker.SetObjectType(node, type);
            return(node);
        }