/// <summary> /// Construct a <see cref="PropertyToken"/>. /// </summary> /// <param name="propertyName">The name of the property.</param> /// <param name="rawText">The token as it appears in the message template.</param> /// <param name="format">The format applied to the property, if any.</param> /// <param name="alignment">The alignment applied to the property, if any.</param> /// <param name="destructuring">The destructuring strategy applied to the property, if any.</param> /// <param name="startIndex">The token's start index in the template.</param> /// <exception cref="ArgumentNullException"></exception> public PropertyToken(string propertyName, string rawText, string format = null, Alignment?alignment = null, Destructuring destructuring = Destructuring.Default, int startIndex = -1) : base(startIndex) { if (propertyName == null) { throw new ArgumentNullException(nameof(propertyName)); } if (rawText == null) { throw new ArgumentNullException(nameof(rawText)); } PropertyName = propertyName; Format = format; Destructuring = destructuring; _rawText = rawText; Alignment = alignment; int position; if (int.TryParse(PropertyName, NumberStyles.None, CultureInfo.InvariantCulture, out position) && position >= 0) { _position = position; } }
LogEventPropertyValue CreatePropertyValue(object value, Destructuring destructuring, int depth) { if (value == null) { return(new ScalarValue(null)); } if (destructuring == Destructuring.Stringify) { return(Stringify(value)); } var valueType = value.GetType(); _depthLimiter.SetCurrentDepth(depth); if (destructuring == Destructuring.Destructure) { if (value is string stringValue) { value = TruncateIfNecessary(stringValue); } } foreach (var scalarConversionPolicy in _scalarConversionPolicies) { if (scalarConversionPolicy.TryConvertToScalar(value, out var converted)) { return(converted); } } if (destructuring == Destructuring.Destructure) { foreach (var destructuringPolicy in _destructuringPolicies) { if (destructuringPolicy.TryDestructure(value, _depthLimiter, out var result)) { return(result); } } } if (TryConvertEnumerable(value, destructuring, valueType, out var enumerableResult)) { return(enumerableResult); } if (TryConvertValueTuple(value, destructuring, valueType, out var tupleResult)) { return(tupleResult); } if (TryConvertCompilerGeneratedType(value, destructuring, valueType, out var compilerGeneratedResult)) { return(compilerGeneratedResult); } return(new ScalarValue(value.ToString())); }
bool TryConvertEnumerable(object value, Destructuring destructuring, Type valueType, out LogEventPropertyValue result) { if (value is IEnumerable enumerable) { // Only dictionaries with 'scalar' keys are permitted, as // more complex keys may not serialize to unique values for // representation in sinks. This check strengthens the expectation // that resulting dictionary is representable in JSON as well // as richer formats (e.g. XML, .NET type-aware...). // Only actual dictionaries are supported, as arbitrary types // can implement multiple IDictionary interfaces and thus introduce // multiple different interpretations. if (TryGetDictionary(value, valueType, out var dictionary)) { result = new DictionaryValue(MapToDictionaryElements(dictionary, destructuring)); return true; IEnumerable<KeyValuePair<ScalarValue, LogEventPropertyValue>> MapToDictionaryElements(IDictionary dictionaryEntries, Destructuring destructure) { var count = 0; foreach (DictionaryEntry entry in dictionaryEntries) { if (++count > _maximumCollectionCount) { yield break; } var pair = new KeyValuePair<ScalarValue, LogEventPropertyValue>( (ScalarValue)_depthLimiter.CreatePropertyValue(entry.Key, destructure), _depthLimiter.CreatePropertyValue(entry.Value, destructure)); if (pair.Key.Value != null) yield return pair; } } } result = new SequenceValue(MapToSequenceElements(enumerable, destructuring)); return true; IEnumerable<LogEventPropertyValue> MapToSequenceElements(IEnumerable sequence, Destructuring destructure) { var count = 0; foreach (var element in sequence) { if (++count > _maximumCollectionCount) { yield break; } yield return _depthLimiter.CreatePropertyValue(element, destructure); } } } result = null; return false; }
LogEventPropertyValue CreatePropertyValue(object value, Destructuring destructuring, int depth) { if (value == null) { return(new ScalarValue(null)); } if (destructuring == Destructuring.Stringify) { return(new ScalarValue(value.ToString())); } // Known literals var valueType = value.GetType(); if (_scalarTypes.Contains(valueType) || valueType.GetTypeInfo().IsEnum) { return(new ScalarValue(value)); } // Dictionaries should be treated here, probably as // structures... var enumerable = value as IEnumerable; if (enumerable != null) { return(new SequenceValue( enumerable.Cast <object>().Select(o => CreatePropertyValue(o, destructuring)))); } // Unknown types if (destructuring == Destructuring.Destructure) { var limiter = new DepthLimiter(depth, this); foreach (var destructuringPolicy in _destructuringPolicies) { LogEventPropertyValue result; if (destructuringPolicy.TryDestructure(value, limiter, out result)) { return(result); } } var typeTag = value.GetType().Name; if (typeTag.Length <= 0 || !char.IsLetter(typeTag[0])) { typeTag = null; } return(new StructureValue(GetProperties(value, limiter), typeTag)); } return(new ScalarValue(value)); }
/// <summary> /// Construct a <see cref="PropertyToken"/>. /// </summary> /// <param name="propertyName">The name of the property.</param> /// <param name="rawText">The token as it appears in the message template.</param> /// <param name="format">The format applied to the property, if any.</param> /// <param name="destructuring">The destructuring strategy applied to the property, if any.</param> /// <exception cref="ArgumentNullException"></exception> public PropertyToken(string propertyName, string rawText, string format = null, Destructuring destructuring = Destructuring.Default) { if (propertyName == null) throw new ArgumentNullException("propertyName"); if (rawText == null) throw new ArgumentNullException("rawText"); _propertyName = propertyName; _format = format; _destructuring = destructuring; _rawText = rawText; }
public LogEventPropertyValue CreatePropertyValue(object value, Destructuring destructuring) { var storedDepth = _currentDepth; var result = DefaultIfMaximumDepth(storedDepth) ?? _propertyValueConverter.CreatePropertyValue(value, destructuring, storedDepth + 1); _currentDepth = storedDepth; return(result); }
/// <summary> /// Construct a <see cref="PropertyToken"/>. /// </summary> /// <param name="propertyName">The name of the property.</param> /// <param name="rawText">The token as it appears in the message template.</param> /// <param name="format">The format applied to the property, if any.</param> /// <param name="destructuring">The destructuring strategy applied to the property, if any.</param> /// <exception cref="ArgumentNullException"></exception> public PropertyToken(string propertyName, string rawText, string format = null, Destructuring destructuring = Destructuring.Default) { if (propertyName == null) { throw new ArgumentNullException("propertyName"); } if (rawText == null) { throw new ArgumentNullException("rawText"); } _propertyName = propertyName; _format = format; _destructuring = destructuring; _rawText = rawText; }
public LogEventPropertyValue CreatePropertyValue(object value, Destructuring destructuring) { try { return CreatePropertyValue(value, destructuring, 1); } catch (Exception ex) { SelfLog.WriteLine("Exception caught while converting property value: {0}", ex); if (_propagateExceptions) throw; return new ScalarValue("Capturing the property value threw an exception: " + ex.GetType().Name); } }
/// <summary> /// Construct a <see cref="PropertyToken"/>. /// </summary> /// <param name="propertyName">The name of the property.</param> /// <param name="rawText">The token as it appears in the message template.</param> /// <param name="format">The format applied to the property, if any.</param> /// <param name="destructuring">The destructuring strategy applied to the property, if any.</param> /// <exception cref="ArgumentNullException"></exception> public PropertyToken(string propertyName, string rawText, string format = null, Destructuring destructuring = Destructuring.Default) { if (propertyName == null) throw new ArgumentNullException("propertyName"); if (rawText == null) throw new ArgumentNullException("rawText"); _propertyName = propertyName; _format = format; _destructuring = destructuring; _rawText = rawText; int position; if (int.TryParse(_propertyName, NumberStyles.None, CultureInfo.InvariantCulture, out position) && position >= 0) { _position = position; } }
bool TryConvertCompilerGeneratedType(object value, Destructuring destructuring, Type valueType, out LogEventPropertyValue result) { if (destructuring == Destructuring.Destructure) { var typeTag = valueType.Name; if (typeTag.Length <= 0 || IsCompilerGeneratedType(valueType)) { typeTag = null; } result = new StructureValue(GetProperties(value), typeTag); return(true); } result = null; return(false); }
/// <summary> /// Construct a <see cref="PropertyToken"/>. /// </summary> /// <param name="propertyName">The name of the property.</param> /// <param name="rawText">The token as it appears in the message template.</param> /// <param name="format">The format applied to the property, if any.</param> /// <param name="alignment">The alignment applied to the property, if any.</param> /// <param name="destructuring">The destructuring strategy applied to the property, if any.</param> /// <param name="startIndex">The token's start index in the template.</param> /// <exception cref="ArgumentNullException"></exception> public PropertyToken(string propertyName, string rawText, string format = null, Alignment? alignment = null, Destructuring destructuring = Destructuring.Default, int startIndex = -1) : base(startIndex) { if (propertyName == null) throw new ArgumentNullException(nameof(propertyName)); if (rawText == null) throw new ArgumentNullException(nameof(rawText)); PropertyName = propertyName; Format = format; Destructuring = destructuring; _rawText = rawText; Alignment = alignment; int position; if (int.TryParse(PropertyName, NumberStyles.None, CultureInfo.InvariantCulture, out position) && position >= 0) { _position = position; } }
bool TryConvertValueTuple(object value, Destructuring destructuring, Type valueType, out LogEventPropertyValue result) { if (!(value is IStructuralEquatable && valueType.IsConstructedGenericType)) { result = null; return(false); } var definition = valueType.GetGenericTypeDefinition(); // Ignore the 8+ value case for now. #if VALUETUPLE if (definition == typeof(ValueTuple <>) || definition == typeof(ValueTuple <,>) || definition == typeof(ValueTuple <, ,>) || definition == typeof(ValueTuple <, , ,>) || definition == typeof(ValueTuple <, , , ,>) || definition == typeof(ValueTuple <, , , , ,>) || definition == typeof(ValueTuple <, , , , , ,>)) #else // ReSharper disable once PossibleNullReferenceException var defn = definition.FullName; if (defn == "System.ValueTuple`1" || defn == "System.ValueTuple`2" || defn == "System.ValueTuple`3" || defn == "System.ValueTuple`4" || defn == "System.ValueTuple`5" || defn == "System.ValueTuple`6" || defn == "System.ValueTuple`7") #endif { var elements = new List <LogEventPropertyValue>(); foreach (var field in valueType.GetTypeInfo().DeclaredFields) { if (field.IsPublic && !field.IsStatic) { var fieldValue = field.GetValue(value); var propertyValue = _depthLimiter.CreatePropertyValue(fieldValue, destructuring); elements.Add(propertyValue); } } result = new SequenceValue(elements); return(true); } result = null; return(false); }
static bool TryGetDestructuringHint(char c, out Destructuring destructuring) { switch (c) { case '@': { destructuring = Destructuring.Destructure; return(true); } case '$': { destructuring = Destructuring.Stringify; return(true); } default: { destructuring = Destructuring.Default; return(false); } } }
/// <summary> /// Construct a <see cref="PropertyToken"/>. /// </summary> /// <param name="propertyName">The name of the property.</param> /// <param name="rawText">The token as it appears in the message template.</param> /// <param name="format">The format applied to the property, if any.</param> /// <param name="destructuring">The destructuring strategy applied to the property, if any.</param> /// <exception cref="ArgumentNullException"></exception> public PropertyToken(string propertyName, string rawText, string format = null, Destructuring destructuring = Destructuring.Default) { if (propertyName == null) { throw new ArgumentNullException("propertyName"); } if (rawText == null) { throw new ArgumentNullException("rawText"); } _propertyName = propertyName; _format = format; _destructuring = destructuring; _rawText = rawText; int position; if (int.TryParse(_propertyName, NumberStyles.None, CultureInfo.InvariantCulture, out position) && position >= 0) { _position = position; } }
/// <summary> /// Create a property value from a .NET object. /// </summary> /// <param name="value">The value.</param> /// <param name="destructuring">Directs the algorithm for determining how the /// object will be represented (e.g. sclar, sequence, structure).</param> /// <returns></returns> public static LogEventPropertyValue For(object value, Destructuring destructuring) { if (value == null) return new ScalarValue(null); if (destructuring == Destructuring.Stringify) return new ScalarValue(value.ToString()); // Known literals var valueType = value.GetType(); if (KnownLiteralTypes.Contains(valueType) || valueType.IsEnum) return new ScalarValue(value); // Dictionaries should be treated here, probably as // structures... var enumerable = value as IEnumerable; if (enumerable != null) { return new SequenceValue( enumerable.Cast<object>().Select(o => For(o, destructuring))); } // Unknown types if (destructuring == Destructuring.Destructure) { var typeTag = value.GetType().Name; if (typeTag.Length <= 0 || !char.IsLetter(typeTag[0])) typeTag = null; return new StructureValue(GetProperties(value, destructuring), typeTag); } return new ScalarValue(value); }
private static IEnumerable<LogEventProperty> GetProperties(object value, Destructuring destructuring) { return value.GetType() .GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty) .Select(p => new LogEventProperty(p.Name, For(p.GetValue(value), destructuring))); }
public LogEventPropertyValue CreatePropertyValue(object value, Destructuring destructuring) { return(DefaultIfMaximumDepth() ?? _propertyValueConverter.CreatePropertyValue(value, destructuring, _currentDepth + 1)); }
LogEventPropertyValue CreatePropertyValue(object value, Destructuring destructuring, int depth) { if (value == null) return new ScalarValue(null); if (destructuring == Destructuring.Stringify) return new ScalarValue(value.ToString()); // Known literals var valueType = value.GetType(); if (_scalarTypes.Contains(valueType) || valueType.GetTypeInfo().IsEnum) return new ScalarValue(value); // Dictionaries should be treated here, probably as // structures... var enumerable = value as IEnumerable; if (enumerable != null) { return new SequenceValue( enumerable.Cast<object>().Select(o => CreatePropertyValue(o, destructuring))); } // Unknown types if (destructuring == Destructuring.Destructure) { var limiter = new DepthLimiter(depth, this); foreach (var destructuringPolicy in _destructuringPolicies) { LogEventPropertyValue result; if (destructuringPolicy.TryDestructure(value, limiter, out result)) return result; } var typeTag = value.GetType().Name; if (typeTag.Length <= 0 || !char.IsLetter(typeTag[0])) typeTag = null; return new StructureValue(GetProperties(value, limiter), typeTag); } return new ScalarValue(value); }
public LogEventPropertyValue CreatePropertyValue(object value, Destructuring destructuring) { return CreatePropertyValue(value, destructuring, 1); }
LogEventPropertyValue CreatePropertyValue(object value, Destructuring destructuring, int depth) { if (value == null) return new ScalarValue(null); if (destructuring == Destructuring.Stringify) return new ScalarValue(value.ToString()); var valueType = value.GetType(); var limiter = new DepthLimiter(depth, this); foreach (var scalarConversionPolicy in _scalarConversionPolicies) { ScalarValue converted; if (scalarConversionPolicy.TryConvertToScalar(value, limiter, out converted)) return converted; } var enumerable = value as IEnumerable; if (enumerable != null) { // Only dictionaries with 'scalar' keys are permitted, as // more complex keys may not serialize to unique values for // representation in sinks. This check strengthens the expectation // that resulting dictionary is representable in JSON as well // as richer formats (e.g. XML, .NET type-aware...). // Only actual dictionaries are supported, as arbitrary types // can implement multiple IDictionary interfaces and thus introduce // multiple different interpretations. if (valueType.IsConstructedGenericType && valueType.GetGenericTypeDefinition() == typeof(Dictionary<,>) && IsValidDictionaryKeyType(valueType.GenericTypeArguments[0])) { return new DictionaryValue(enumerable.Cast<dynamic>() .Select(kvp => new KeyValuePair<ScalarValue, LogEventPropertyValue>( (ScalarValue)limiter.CreatePropertyValue(kvp.Key, destructuring), limiter.CreatePropertyValue(kvp.Value, destructuring))) .Where(kvp => kvp.Key.Value != null)); // Limiting may kick in } return new SequenceValue( enumerable.Cast<object>().Select(o => limiter.CreatePropertyValue(o, destructuring))); } // Unknown types if (destructuring == Destructuring.Destructure) { foreach (var destructuringPolicy in _destructuringPolicies) { LogEventPropertyValue result; if (destructuringPolicy.TryDestructure(value, limiter, out result)) return result; } var typeTag = value.GetType().Name; if (typeTag.Length <= 0 || !char.IsLetter(typeTag[0])) typeTag = null; return new StructureValue(GetProperties(value, limiter), typeTag); } return new ScalarValue(value.ToString()); }
private static bool TryGetDestructuringHint(char c, out Destructuring destructuring) { switch (c) { case '@': { destructuring = Destructuring.Destructure; return true; } case '$': { destructuring = Destructuring.Stringify; return true; } default: { destructuring = Destructuring.Default; return false; } } }
public PropertyToken(string propertyName, string rawText, string formatObsolete, Destructuring destructuringObsolete) : this(propertyName, rawText, formatObsolete, null, destructuringObsolete) { }
public LogEventPropertyValue CreatePropertyValue(object value, Destructuring destructuring) { return(CreatePropertyValue(value, destructuring, 1)); }
LogEventPropertyValue CreatePropertyValue(object value, Destructuring destructuring, int depth) { if (value == null) return new ScalarValue(null); if (destructuring == Destructuring.Stringify) return new ScalarValue(value.ToString()); var valueType = value.GetType(); var limiter = new DepthLimiter(depth, _maximumDestructuringDepth, this); foreach (var scalarConversionPolicy in _scalarConversionPolicies) { ScalarValue converted; if (scalarConversionPolicy.TryConvertToScalar(value, limiter, out converted)) return converted; } if (destructuring == Destructuring.Destructure) { foreach (var destructuringPolicy in _destructuringPolicies) { LogEventPropertyValue result; if (destructuringPolicy.TryDestructure(value, limiter, out result)) return result; } } var enumerable = value as IEnumerable; if (enumerable != null) { // Only dictionaries with 'scalar' keys are permitted, as // more complex keys may not serialize to unique values for // representation in sinks. This check strengthens the expectation // that resulting dictionary is representable in JSON as well // as richer formats (e.g. XML, .NET type-aware...). // Only actual dictionaries are supported, as arbitrary types // can implement multiple IDictionary interfaces and thus introduce // multiple different interpretations. if (IsValueTypeDictionary(valueType)) { var typeInfo = typeof(KeyValuePair<,>).MakeGenericType(valueType.GenericTypeArguments).GetTypeInfo(); var keyProperty = typeInfo.GetDeclaredProperty("Key"); var valueProperty = typeInfo.GetDeclaredProperty("Value"); return new DictionaryValue(enumerable.Cast<object>() .Select(kvp => new KeyValuePair<ScalarValue, LogEventPropertyValue>( (ScalarValue)limiter.CreatePropertyValue(keyProperty.GetValue(kvp), destructuring), limiter.CreatePropertyValue(valueProperty.GetValue(kvp), destructuring))) .Where(kvp => kvp.Key.Value != null)); } return new SequenceValue( enumerable.Cast<object>().Select(o => limiter.CreatePropertyValue(o, destructuring))); } if (destructuring == Destructuring.Destructure) { var type = value.GetType(); var typeTag = type.Name; if (typeTag.Length <= 0 || IsCompilerGeneratedType(type)) { typeTag = null; } return new StructureValue(GetProperties(value, limiter), typeTag); } return new ScalarValue(value.ToString()); }
TemplatePropertyValue CreatePropertyValue(object value, Destructuring destructuring, int depth) { if (value == null) return new ScalarValue(null); if (destructuring == Destructuring.Stringify) return new ScalarValue(value.ToString()); var valueType = value.GetType(); var limiter = new DepthLimiter(depth, _maximumDestructuringDepth, this); foreach (var scalarConversionPolicy in _scalarConversionPolicies) { ScalarValue converted; if (scalarConversionPolicy.TryConvertToScalar(value, limiter, out converted)) return converted; } if (destructuring == Destructuring.Destructure) { foreach (var destructuringPolicy in _destructuringPolicies) { TemplatePropertyValue result; if (destructuringPolicy.TryDestructure(value, limiter, out result)) return result; } } #region IEnumerable->SequenceValue|DictionaryValue var enumerable = value as IEnumerable; if (enumerable != null) { // Only dictionaries with 'scalar' keys are permitted, as // more complex keys may not serialize to unique values for // representation in sinks. This check strengthens the expectation // that resulting dictionary is representable in JSON as well // as richer formats (e.g. XML, .NET type-aware...). // Only actual dictionaries are supported, as arbitrary types // can implement multiple IDictionary interfaces and thus introduce // multiple different interpretations. if (IsValueTypeDictionary(valueType)) { Func<object, object> getKey; Func<object, object> getValue; #if USE_REFLECTION_40 PropertyInfo keyProperty = null; getKey = o => (keyProperty ?? (keyProperty = o.GetType().GetProperty("Key"))).GetValue(o, null); PropertyInfo valueProperty = null; getValue = o => (valueProperty ?? (valueProperty = o.GetType().GetProperty("Value"))).GetValue(o, null); #else PropertyInfo keyProperty = null; getKey = o => (keyProperty ?? (keyProperty = o.GetType().GetRuntimeProperty("Key"))).GetValue(o); PropertyInfo valueProperty = null; getValue = o => (valueProperty ?? (valueProperty = o.GetType().GetRuntimeProperty("Value"))).GetValue(o); #endif return new DictionaryValue(enumerable .Cast<object>() .Where(o => o != null) .Select(o => new { Key = getKey(o), Value = getValue(o) }) .Select(o => new KeyValuePair<ScalarValue, TemplatePropertyValue>( key: (ScalarValue)limiter.CreatePropertyValue(o.Key, destructuring), value: limiter.CreatePropertyValue(o.Value, destructuring)) ) ); } return new SequenceValue( enumerable.Cast<object>().Select(o => limiter.CreatePropertyValue(o, destructuring))); } #endregion if (destructuring == Destructuring.Destructure) { var typeTag = value.GetType().Name; if (typeTag.Length <= 0 || !char.IsLetter(typeTag[0])) typeTag = null; return new StructureValue(GetProperties(value, limiter), typeTag); } return new ScalarValue(value.ToString()); }
public LogEventPropertyValue CreatePropertyValue(object value, Destructuring destructuring) { return DefaultIfMaximumDepth() ?? _propertyValueConverter.CreatePropertyValue(value, destructuring, _currentDepth + 1); }
TemplatePropertyValue CreatePropertyValue(object value, Destructuring destructuring, int depth) { if (value == null) { return(new ScalarValue(null)); } if (destructuring == Destructuring.Stringify) { return(new ScalarValue(value.ToString())); } var valueType = value.GetType(); var limiter = new DepthLimiter(depth, _maximumDestructuringDepth, this); foreach (var scalarConversionPolicy in _scalarConversionPolicies) { ScalarValue converted; if (scalarConversionPolicy.TryConvertToScalar(value, limiter, out converted)) { return(converted); } } if (destructuring == Destructuring.Destructure) { foreach (var destructuringPolicy in _destructuringPolicies) { TemplatePropertyValue result; if (destructuringPolicy.TryDestructure(value, limiter, out result)) { return(result); } } } var enumerable = value as IEnumerable; if (enumerable != null) { // Only dictionaries with 'scalar' keys are permitted, as // more complex keys may not serialize to unique values for // representation in sinks. This check strengthens the expectation // that resulting dictionary is representable in JSON as well // as richer formats (e.g. XML, .NET type-aware...). // Only actual dictionaries are supported, as arbitrary types // can implement multiple IDictionary interfaces and thus introduce // multiple different interpretations. if (IsValueTypeDictionary(valueType)) { Func <object, object> getKey; Func <object, object> getValue; #if !REFLECTION_API_EVOLVED // https://blogs.msdn.microsoft.com/dotnet/2012/08/28/evolving-the-reflection-api/ PropertyInfo keyProperty = null; getKey = o => (keyProperty ?? (keyProperty = o.GetType().GetProperty("Key"))).GetValue(o, null); PropertyInfo valueProperty = null; getValue = o => (valueProperty ?? (valueProperty = o.GetType().GetProperty("Value"))).GetValue(o, null); #else PropertyInfo keyProperty = null; getKey = o => (keyProperty ?? (keyProperty = o.GetType().GetRuntimeProperty("Key"))).GetValue(o); PropertyInfo valueProperty = null; getValue = o => (valueProperty ?? (valueProperty = o.GetType().GetRuntimeProperty("Value"))).GetValue(o); #endif // TODO: stop using LINQ return(new DictionaryValue(enumerable .Cast <object>() .Where(o => o != null) .Select(o => new { Key = getKey(o), Value = getValue(o) }) .Select(o => new KeyValuePair <ScalarValue, TemplatePropertyValue>( key: (ScalarValue)limiter.CreatePropertyValue(o.Key, destructuring), value: limiter.CreatePropertyValue(o.Value, destructuring)) ) )); } return(new SequenceValue( enumerable.Cast <object>().Select(o => limiter.CreatePropertyValue(o, destructuring)))); } if (destructuring == Destructuring.Destructure) { var type = value.GetType(); var typeTag = type.Name; #if REFLECTION_API_EVOLVED if (typeTag.Length <= 0 || IsCompilerGeneratedType(type)) { typeTag = null; } #else if (typeTag.Length <= 0 || !char.IsLetter(typeTag[0])) { typeTag = null; } #endif return(new StructureValue(GetProperties(value, limiter), typeTag)); } return(new ScalarValue(value.ToString())); }
LogEventPropertyValue CreatePropertyValue(object value, Destructuring destructuring, int depth) { if (value == null) { return(new ScalarValue(null)); } if (destructuring == Destructuring.Stringify) { return(new ScalarValue(value.ToString())); } // Known literals var valueType = value.GetType(); if (IsScalarType(valueType) || valueType.GetTypeInfo().IsEnum) { return(new ScalarValue(value)); } var enumerable = value as IEnumerable; if (enumerable != null) { // Only dictionaries with 'scalar' keys are permitted, as // more complex keys may not serialize to unique values for // representation in sinks. This check strengthens the expectation // that resulting dictionary is representable in JSON as well // as richer formats (e.g. XML, .NET type-aware...). // Only actual dictionaries are supported, as arbitrary types // can implement multiple IDictionary interfaces and thus introduce // multiple different interpretations. if (valueType.IsConstructedGenericType && valueType.GetGenericTypeDefinition() == typeof(Dictionary <,>) && IsScalarType(valueType.GenericTypeArguments[0])) { return(new DictionaryValue( enumerable.Cast <dynamic>().Select(kvp => new KeyValuePair <ScalarValue, LogEventPropertyValue>( (ScalarValue)CreatePropertyValue(kvp.Key, destructuring), CreatePropertyValue(kvp.Value, destructuring))))); } return(new SequenceValue( enumerable.Cast <object>().Select(o => CreatePropertyValue(o, destructuring)))); } // Unknown types if (destructuring == Destructuring.Destructure) { var limiter = new DepthLimiter(depth, this); foreach (var destructuringPolicy in _destructuringPolicies) { LogEventPropertyValue result; if (destructuringPolicy.TryDestructure(value, limiter, out result)) { return(result); } } var typeTag = value.GetType().Name; if (typeTag.Length <= 0 || !char.IsLetter(typeTag[0])) { typeTag = null; } return(new StructureValue(GetProperties(value, limiter), typeTag)); } return(new ScalarValue(value)); }
LogEventPropertyValue CreatePropertyValue(object value, Destructuring destructuring, int depth) { if (value == null) { return(new ScalarValue(null)); } if (destructuring == Destructuring.Stringify) { return(new ScalarValue(value.ToString())); } var valueType = value.GetType(); var limiter = new DepthLimiter(depth, _maximumDestructuringDepth, this); foreach (var scalarConversionPolicy in _scalarConversionPolicies) { ScalarValue converted; if (scalarConversionPolicy.TryConvertToScalar(value, limiter, out converted)) { return(converted); } } if (destructuring == Destructuring.Destructure) { foreach (var destructuringPolicy in _destructuringPolicies) { LogEventPropertyValue result; if (destructuringPolicy.TryDestructure(value, limiter, out result)) { return(result); } } } var enumerable = value as IEnumerable; if (enumerable != null) { // Only dictionaries with 'scalar' keys are permitted, as // more complex keys may not serialize to unique values for // representation in sinks. This check strengthens the expectation // that resulting dictionary is representable in JSON as well // as richer formats (e.g. XML, .NET type-aware...). // Only actual dictionaries are supported, as arbitrary types // can implement multiple IDictionary interfaces and thus introduce // multiple different interpretations. if (IsValueTypeDictionary(valueType)) { var typeInfo = typeof(KeyValuePair <,>).MakeGenericType(valueType.GenericTypeArguments).GetTypeInfo(); var keyProperty = typeInfo.GetDeclaredProperty("Key"); var valueProperty = typeInfo.GetDeclaredProperty("Value"); return(new DictionaryValue(enumerable.Cast <object>() .Select(kvp => new KeyValuePair <ScalarValue, LogEventPropertyValue>( (ScalarValue)limiter.CreatePropertyValue(keyProperty.GetValue(kvp), destructuring), limiter.CreatePropertyValue(valueProperty.GetValue(kvp), destructuring))) .Where(kvp => kvp.Key.Value != null))); } return(new SequenceValue( enumerable.Cast <object>().Select(o => limiter.CreatePropertyValue(o, destructuring)))); } if (destructuring == Destructuring.Destructure) { var type = value.GetType(); var typeTag = type.Name; if (typeTag.Length <= 0 || IsCompilerGeneratedType(type)) { typeTag = null; } return(new StructureValue(GetProperties(value, limiter), typeTag)); } return(new ScalarValue(value.ToString())); }