Ejemplo n.º 1
0
        private List <Element> RecursiveGatherSubElements(object obj)
        {
            var elements = new List <Element>();

            if (obj == null)
            {
                return(elements);
            }

            var e = obj as Element;

            if (e != null && Elements.ContainsKey(e.Id))
            {
                // Do nothing. The Element has already
                // been added. This assumes that that the sub-elements
                // have been added as well and we don't need to continue.
                return(elements);
            }

            var t = obj.GetType();

            // Ignore value types and strings
            // as they won't have properties that
            // could be elements.
            if (!t.IsClass || t == typeof(string))
            {
                return(elements);
            }

            var props            = t.GetProperties(BindingFlags.Public | BindingFlags.Instance);
            var constrainedProps = props.Where(p => IsValidForRecursiveAddition(p.PropertyType));

            foreach (var p in constrainedProps)
            {
                try
                {
                    var pValue = p.GetValue(obj, null);
                    if (pValue == null)
                    {
                        continue;
                    }

                    var elems = pValue as IList;
                    if (elems != null)
                    {
                        foreach (var item in elems)
                        {
                            elements.AddRange(RecursiveGatherSubElements(item));
                        }
                        continue;
                    }

                    // Get the properties dictionaries.
                    var dict = pValue as IDictionary;
                    if (dict != null)
                    {
                        foreach (var value in dict.Values)
                        {
                            elements.AddRange(RecursiveGatherSubElements(value));
                        }
                        continue;
                    }

                    elements.AddRange(RecursiveGatherSubElements(pValue));
                }
                catch (Exception ex)
                {
                    throw new Exception($"The {p.Name} property or one of its children was not valid for introspection. Check the inner exception for details.", ex);
                }
            }

            if (e != null)
            {
                elements.Add(e);
            }

            return(elements);
        }