Skip to content

Commit

Permalink
Merge pull request serilog#622 from Pvlerick/issue-618
Browse files Browse the repository at this point in the history
Added function to detect anonymous types and appropriate tests
  • Loading branch information
nblumhardt committed Jan 14, 2016
2 parents b195b43 + ff447f5 commit 2a632ba
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 2 deletions.
23 changes: 21 additions & 2 deletions src/Serilog/Parameters/PropertyValueConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@

#if NET40
using Serilog.Platform;
#else
using System.Runtime.CompilerServices;
#endif

namespace Serilog.Parameters
Expand Down Expand Up @@ -154,9 +156,12 @@ LogEventPropertyValue CreatePropertyValue(object value, Destructuring destructur

if (destructuring == Destructuring.Destructure)
{
var typeTag = value.GetType().Name;
if (typeTag.Length <= 0 || !char.IsLetter(typeTag[0]))
var type = value.GetType();
var typeTag = type.Name;
if (typeTag.Length <= 0 || IsCompilerGeneratedType(type))
{
typeTag = null;
}

return new StructureValue(GetProperties(value, limiter), typeTag);
}
Expand Down Expand Up @@ -214,5 +219,19 @@ static IEnumerable<LogEventProperty> GetProperties(object value, ILogEventProper
yield return new LogEventProperty(prop.Name, recursive.CreatePropertyValue(propValue, true));
}
}

#if !NET40
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
internal static bool IsCompilerGeneratedType(Type type)
{
var typeInfo = type.GetTypeInfo();
var typeName = type.Name;

//C# Anonymous types always start with "<>" and VB's start with "VB$"
return typeInfo.IsGenericType && typeInfo.IsSealed && typeInfo.IsNotPublic && type.Namespace == null
&& (typeName[0] == '<'
|| (typeName.Length > 2 && typeName[0] == 'V' && typeName[1] == 'B' && typeName[2] == '$'));
}
}
}
2 changes: 2 additions & 0 deletions src/Serilog/Platform/TypeInfo-net40.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ public TypeInfo(Type type)
public IEnumerable<PropertyInfo> DeclaredProperties => Type.GetProperties();

public bool IsAssignableFrom(TypeInfo targetType) => Type.IsAssignableFrom(targetType.Type);

public bool IsNotPublic => Type.IsNotPublic;
}
}
#endif
10 changes: 10 additions & 0 deletions test/Serilog.Tests/Parameters/PropertyValueConverterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,16 @@ public void ItemPropertiesNotAreIgnoredWhenDestructuring()
var item = pv.Properties.Single();
Assert.Equal("Item", item.Name);
}

[Fact]
public void CSharpAnonymousTypesAreRecognizedWhenDestructuring()
{
var o = new { Foo = "Bar" };
var result = _converter.CreatePropertyValue(o, true);
Assert.Equal(typeof(StructureValue), result.GetType());
var structuredValue = (StructureValue)result;
Assert.Equal(null, structuredValue.TypeTag);
}
}
}

Expand Down

0 comments on commit 2a632ba

Please sign in to comment.