예제 #1
0
        public static void WalkObjectGraph(object currentNode, bool walkCollections, WalkGraphAction action, Stack <object> objectStack, Func <PropertyInfo, bool> performActionOnProperty, Func <Type, bool> interestingTypeFunction = null)
        {
            if (currentNode == null)
            {
                return;
            }

            if (null == objectStack)
            {
                // Maintain a stack of objects in the hierarchy so we don't get stuck processing loops in the graph
                objectStack = new Stack <object>();
            }
            else if (objectStack.Contains(currentNode))
            {
                // We've already walked this object, so we have a circular reference, let's not overflow the stack.
                return;
            }

            objectStack.Push(currentNode);

            interestingTypeFunction = interestingTypeFunction ?? (t => true);

            // Act on the current object
            if (interestingTypeFunction(currentNode.GetType()))
            {
                action(null, currentNode, objectStack);
            }

            // Walk down into the object graph for properties that have objects
            var objectProperties = currentNode.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);

            foreach (var prop in objectProperties)
            {
                // Skip read or write only properties
                if (!prop.CanRead || !prop.CanWrite)
                {
                    continue;
                }

                // Check to see if we should perform the action() on this property
                if (performActionOnProperty(prop) && interestingTypeFunction(prop.GetType()))
                {
                    action(prop, currentNode, objectStack);
                }

                // Check to see if this property holds an object we can walk into
                object value;
                try
                {
                    value = prop.GetValue(currentNode);
                }
                catch (Exception)
                {
                    continue;
                }

                if (null != value)
                {
                    if (walkCollections && value is IEnumerable && !(value is string))
                    {
                        foreach (var obj in (IEnumerable)value)
                        {
                            WalkObjectGraph(obj, walkCollections, action, objectStack, performActionOnProperty, interestingTypeFunction);
                        }
                    }
                    else if (!(value is IEnumerable))
                    {
                        WalkObjectGraph(value, walkCollections, action, objectStack, performActionOnProperty, interestingTypeFunction);
                    }
                }
            }
            objectStack.Pop();
        }
예제 #2
0
 internal static void WalkObjectGraph <TAttribute>(object source, bool intoCollections, WalkGraphAction action, Stack <object> parentObjectStack = null)
     where TAttribute : Attribute
 {
     WalkObjectGraph(source, intoCollections, action, parentObjectStack, p => p.GetCustomAttributes <TAttribute>(true).Any(), null);
 }