Exemplo n.º 1
0
 /// <summary>
 /// Dumps the contents of the specified value and returns the dumped contents as a string
 /// </summary>
 /// <param name="value">The object to dump</param>
 /// <param name="name">Name to give to the object in the dump; if null the name is just "object"</param>
 /// <param name="options">A DumpOptions object that defines options for what the dump contains</param>
 /// <returns>The dumped contents of the object as multi-line string</returns>
 public static string Dump(object value, string name, DumperOptions options)
 {
     using (var writer = new StringWriter(CultureInfo.InvariantCulture))
     {
         Dump(value, name, writer, options);
         return(writer.ToString());
     }
 }
Exemplo n.º 2
0
        /// <summary>
        /// Dumps the specified value to the given TextWriter using the specified name
        /// </summary>
        /// <param name="value">The value to dump to the writer</param>
        /// <param name="name">The name of the value being dumped</param>
        /// <param name="writer">The TextWriter to dump the value to</param>
        /// <param name="options">A DumpOptions object that defines options for what the dump contains</param>
        public static void Dump(object value, string name, TextWriter writer, DumperOptions options)
        {
            if (name == null)
            {
                name = "object";
            }
            if (writer == null)
            {
                throw new ArgumentNullException(nameof(writer));
            }
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            var idGenerator = new ObjectIDGenerator();

            InternalDump(0, name, value, null, writer, idGenerator, true, options);
        }
Exemplo n.º 3
0
 public static void Dump(object obj, string name, DumperOptions options)
 {
     Debug(Dumper.Dump(obj, name, options));
 }
Exemplo n.º 4
0
        private static void InternalDump(int indentationLevel, string name, object value, MemberInfo memberInfo,
                                         TextWriter writer, ObjectIDGenerator idGenerator, bool recursiveDump, DumperOptions options)
        {
            var indentation = new string(' ', indentationLevel *IndentationSpace);
            //var indentation2 = new string(' ', (indentationLevel + 1) * INDENTATION_SPACE);

            string accessModifiers  = GetAccessModifiers(memberInfo);
            string declaredTypeName = ImproveTypeName(GetDeclaredTypeName(memberInfo));
            string propertyMethods  = PropertyMethods(memberInfo);

            if (value == null)
            {
                writer.WriteLine($"{indentation}{accessModifiers}{declaredTypeName}{name}{propertyMethods} = <null>");
                return;
            }

            Type type = value.GetType();

            // figure out if this is an object that has already been dumped, or is currently being dumped
            string keyRef    = string.Empty;
            string keyPrefix = string.Empty;

            if (!type.IsValueType)
            {
                bool firstTime;
                long key = idGenerator.GetId(value, out firstTime);
                if (!firstTime)
                {
                    keyRef = string.Format(CultureInfo.InvariantCulture, " (see #{0})", key);
                }
                else
                {
                    keyPrefix = string.Format(CultureInfo.InvariantCulture, "#{0}: ", key);
                }
            }

            // work out how a simple dump of the value should be done
            bool   isString = value is string;
            string typeName = ImproveTypeName(value.GetType().ToString());

            typeName = (declaredTypeName.TrimEnd() == typeName) ? "" : " [" + typeName + "]";
            string formattedValue = value.ToString();

            var exception = value as Exception;

            if (exception != null)
            {
                formattedValue = exception.GetType().Name + ": " + exception.Message;
            }

            if (value is bool)
            {
                formattedValue = value.ToString().ToLowerInvariant();
            }

            // escape tabs and line feeds
            formattedValue = formattedValue.Replace("\t", "\\t").Replace("\n", "\\n").Replace("\r", "\\r");

            // Give non-numerical values double-quotes
            if (!(value is int || value is float || value is byte || value is decimal || value is double || value is long ||
                  value is short || value is uint || value is ulong || value is ushort || value is bool || value is sbyte))
            {
                formattedValue = "\"" + formattedValue + "\"";
            }

            // chop at MAX_CONTENT characters
            int length = formattedValue.Length;

            if (length > MaxValueLength)
            {
                formattedValue = formattedValue.Substring(0, MaxValueLength);
            }
            if (length > MaxValueLength)
            {
                formattedValue += " (+" + (length - MaxValueLength) + " chars)";
            }

            var collection = value as ICollection;

            if (collection != null)
            {
                formattedValue += " (Count = " + collection.Count + ")";
            }

            //writer.WriteLine($"{indentation}{keyPrefix}{accessModifiers}{declaredTypeName}{name}{propertyMethods} = {formattedValue}{typeName}{keyRef}");
            // Removed keyref info for now, because it makes output cluttered; let's think about some better visualization later
            writer.WriteLine($"{indentation}{accessModifiers}{declaredTypeName}{name}{propertyMethods} = {formattedValue}{typeName}");

            // Avoid dumping objects we've already dumped, or is already in the process of dumping
            if (keyRef.Length > 0)
            {
                return;
            }

            // don't dump strings, we already got at around 80 characters of those dumped
            if (isString)
            {
                return;
            }

            // don't dump value-types in the System namespace
            if (type.IsValueType && type.FullName == "System." + type.Name)
            {
                return;
            }

            // Avoid certain types that will result in endless recursion
            if (type.FullName == "System.Reflection." + type.Name)
            {
                return;
            }

            // Avoid types that are excluded in options
            if (options.DontDumpTypes.Contains(type))
            {
                return;
            }

            if (value is System.Security.Principal.SecurityIdentifier)
            {
                return;
            }

            if (!recursiveDump)
            {
                return;
            }

            if (indentationLevel / 2 > options.MaxDepth - 1)
            {
                return;
            }

            // Iterate enumerable
            var enumerable = value as IEnumerable;

            if (enumerable != null)
            {
                if (options.IterateEnumerable)
                {
                    int i = 0;
                    foreach (var element in enumerable)
                    {
                        InternalDump(indentationLevel + 2, "[" + i + "]", element, null, writer, idGenerator, true, options);
                        i++;
                        if (i >= 100)
                        {
                            writer.WriteLine(new string(' ', (indentationLevel + 2) * IndentationSpace) + "[ enumeration truncated ]");
                            break;
                        }
                    }
                }

                // Don't show members of enumerable if option is set
                if (!options.WithEnumerableMembers)
                {
                    return;
                }
            }


            var bfPublic = options.WithNonPublic ? BindingFlags.NonPublic : BindingFlags.Default;
            var bfStatic = options.WithStatic ? BindingFlags.Static : BindingFlags.Default;

            PropertyInfo[] properties =
                (from property in type.GetProperties(BindingFlags.Instance | bfStatic | BindingFlags.Public | bfPublic)
                 where property.GetIndexParameters().Length == 0 &&
                 property.CanRead
                 select property).ToArray();
            IEnumerable <FieldInfo> fields = !options.WithFields
                ? Enumerable.Empty <FieldInfo>()
                : type.GetFields(BindingFlags.Instance | bfStatic | BindingFlags.Public | bfPublic);

            if (!properties.Any() && !fields.Any())
            {
                return;
            }

            writer.WriteLine($"{indentation}{{");

            if (fields.Any())
            {
                //writer.WriteLine($"{indentation2}fields {{");
                foreach (FieldInfo field in fields)
                {
                    try
                    {
                        object fieldValue = field.GetValue(value);
                        InternalDump(indentationLevel + 2, field.Name, fieldValue, field, writer, idGenerator, true, options);
                    }
                    catch (TargetInvocationException ex)
                    {
                        InternalDump(indentationLevel + 2, field.Name, ex, field, writer, idGenerator, false, options);
                    }
                }
                //writer.WriteLine($"{indentation2}}}");
            }

            if (properties.Any())
            {
                //writer.WriteLine($"{indentation2}properties {{");
                foreach (PropertyInfo property in properties)
                {
                    try
                    {
                        object propertyValue = property.GetValue(value, null);
                        InternalDump(indentationLevel + 2, property.Name, propertyValue, property, writer, idGenerator, true, options);
                    }
                    catch (TargetInvocationException ex)
                    {
                        InternalDump(indentationLevel + 2, property.Name, ex.InnerException, property, writer, idGenerator, false, options);
                    }
                    catch (Exception ex)
                    {
                        InternalDump(indentationLevel + 2, property.Name, ex, property, writer, idGenerator, false, options);
                    }
                }
                //writer.WriteLine($"{indentation2}}}");
            }
            writer.WriteLine($"{indentation}}}");
        }
Exemplo n.º 5
0
 /// <summary>
 /// Dumps the contents of the specified value and returns the dumped contents as a string.
 /// </summary>
 /// <param name="value">The object to dump</param>
 /// <param name="options">A DumpOptions object that defines options for what the dump contains</param>
 /// <returns>The dumped contents of the object as multi-line string</returns>
 public static string Dump(object value, DumperOptions options)
 {
     return(Dump(value, null, options));
 }