Пример #1
0
        /// <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()));
        }
Пример #3
0
        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;
        }
Пример #4
0
        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));
        }
Пример #5
0
 /// <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;
 }
Пример #6
0
            public LogEventPropertyValue CreatePropertyValue(object value, Destructuring destructuring)
            {
                var storedDepth = _currentDepth;

                var result = DefaultIfMaximumDepth(storedDepth) ??
                             _propertyValueConverter.CreatePropertyValue(value, destructuring, storedDepth + 1);

                _currentDepth = storedDepth;

                return(result);
            }
Пример #7
0
 /// <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;
 }
Пример #8
0
        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);
            }
        }
Пример #9
0
        /// <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;
            }
        }
Пример #10
0
        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);
        }
Пример #11
0
        /// <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;
            }
        }
Пример #12
0
        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);
            }
            }
        }
Пример #14
0
        /// <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;
            }
        }
Пример #15
0
        /// <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);
        }
Пример #16
0
 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)));
 }
Пример #17
0
 public LogEventPropertyValue CreatePropertyValue(object value, Destructuring destructuring)
 {
     return(DefaultIfMaximumDepth() ??
            _propertyValueConverter.CreatePropertyValue(value, destructuring, _currentDepth + 1));
 }
Пример #18
0
        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);
        }
Пример #19
0
 public LogEventPropertyValue CreatePropertyValue(object value, Destructuring destructuring)
 {
     return CreatePropertyValue(value, destructuring, 1);
 }
Пример #20
0
        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());
        }
Пример #21
0
 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;
         }
     }
 }
Пример #22
0
 public PropertyToken(string propertyName, string rawText, string formatObsolete, Destructuring destructuringObsolete)
     : this(propertyName, rawText, formatObsolete, null, destructuringObsolete)
 {
 }
Пример #23
0
 public PropertyToken(string propertyName, string rawText, string formatObsolete, Destructuring destructuringObsolete)
     : this(propertyName, rawText, formatObsolete, null, destructuringObsolete)
 {
 }
Пример #24
0
        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);
            }
        }
Пример #25
0
 public LogEventPropertyValue CreatePropertyValue(object value, Destructuring destructuring)
 {
     return(CreatePropertyValue(value, destructuring, 1));
 }
Пример #26
0
        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());
        }
Пример #27
0
        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());
        }
Пример #28
0
 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()));
        }
Пример #30
0
        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));
        }
Пример #31
0
        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()));
        }