static List <PropertyConverter> GetPropertyConvertersForType(Type type)
        {
            var          propertyConverters = new List <PropertyConverter>();
            BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly;

            // Loop through the type hierarchy to find all [DataMember] attributes which belong to [DataContract] classes.
            while (type != null && type.GetCustomAttribute <DataContractAttribute>() != null)
            {
                foreach (MemberInfo member in type.GetMembers(flags))
                {
                    DataMemberAttribute dataMember = member.GetCustomAttribute <DataMemberAttribute>();
                    if (dataMember == null)
                    {
                        continue;
                    }

                    PropertyInfo property = member as PropertyInfo;
                    FieldInfo    field    = member as FieldInfo;
                    if (property == null && field == null)
                    {
                        throw new InvalidDataContractException("Only fields and properties can be marked as [DataMember].");
                    }
                    else if (property != null && (!property.CanWrite || !property.CanRead))
                    {
                        throw new InvalidDataContractException("[DataMember] properties must be both readable and writeable.");
                    }

                    // Timestamp is a reserved property name in Table Storage, so the name needs to be changed.
                    string propertyName = dataMember.Name ?? member.Name;
                    if (string.Equals(propertyName, "Timestamp", StringComparison.OrdinalIgnoreCase))
                    {
                        propertyName = "_Timestamp";
                    }

                    Func <object, EntityProperty>   getEntityPropertyFunc;
                    Action <object, EntityProperty> setObjectPropertyFunc;

                    Type memberValueType = property != null ? property.PropertyType : field.FieldType;
                    if (typeof(string).IsAssignableFrom(memberValueType))
                    {
                        if (property != null)
                        {
                            getEntityPropertyFunc = o => EntityProperty.GeneratePropertyForString((string)property.GetValue(o));
                            setObjectPropertyFunc = (o, e) => property.SetValue(o, e.StringValue);
                        }
                        else
                        {
                            getEntityPropertyFunc = o => EntityProperty.GeneratePropertyForString((string)field.GetValue(o));
                            setObjectPropertyFunc = (o, e) => field.SetValue(o, e.StringValue);
                        }
                    }
                    else if (memberValueType.IsEnum)
                    {
                        // Enums are serialized as strings for readability.
                        if (property != null)
                        {
                            getEntityPropertyFunc = o => EntityProperty.GeneratePropertyForString(property.GetValue(o).ToString());
                            setObjectPropertyFunc = (o, e) => property.SetValue(o, Enum.Parse(memberValueType, e.StringValue));
                        }
                        else
                        {
                            getEntityPropertyFunc = o => EntityProperty.GeneratePropertyForString(field.GetValue(o).ToString());
                            setObjectPropertyFunc = (o, e) => field.SetValue(o, Enum.Parse(memberValueType, e.StringValue));
                        }
                    }
                    else if (typeof(int?).IsAssignableFrom(memberValueType))
                    {
                        if (property != null)
                        {
                            getEntityPropertyFunc = o => EntityProperty.GeneratePropertyForInt((int)property.GetValue(o));
                            setObjectPropertyFunc = (o, e) => property.SetValue(o, e.Int32Value);
                        }
                        else
                        {
                            getEntityPropertyFunc = o => EntityProperty.GeneratePropertyForInt((int)field.GetValue(o));
                            setObjectPropertyFunc = (o, e) => field.SetValue(o, e.Int32Value);
                        }
                    }
                    else if (typeof(long?).IsAssignableFrom(memberValueType))
                    {
                        if (property != null)
                        {
                            getEntityPropertyFunc = o => EntityProperty.GeneratePropertyForLong((long)property.GetValue(o));
                            setObjectPropertyFunc = (o, e) => property.SetValue(o, e.Int64Value);
                        }
                        else
                        {
                            getEntityPropertyFunc = o => EntityProperty.GeneratePropertyForLong((long)field.GetValue(o));
                            setObjectPropertyFunc = (o, e) => field.SetValue(o, e.Int64Value);
                        }
                    }
                    else if (typeof(bool?).IsAssignableFrom(memberValueType))
                    {
                        if (property != null)
                        {
                            getEntityPropertyFunc = o => EntityProperty.GeneratePropertyForBool((bool)property.GetValue(o));
                            setObjectPropertyFunc = (o, e) => property.SetValue(o, e.BooleanValue);
                        }
                        else
                        {
                            getEntityPropertyFunc = o => EntityProperty.GeneratePropertyForBool((bool)field.GetValue(o));
                            setObjectPropertyFunc = (o, e) => field.SetValue(o, e.BooleanValue);
                        }
                    }
                    else if (typeof(DateTime?).IsAssignableFrom(memberValueType))
                    {
                        if (property != null)
                        {
                            getEntityPropertyFunc = o => EntityProperty.GeneratePropertyForDateTimeOffset((DateTime?)property.GetValue(o));
                            setObjectPropertyFunc = (o, e) => property.SetValue(o, e.DateTime);
                        }
                        else
                        {
                            getEntityPropertyFunc = o => EntityProperty.GeneratePropertyForDateTimeOffset((DateTime?)field.GetValue(o));
                            setObjectPropertyFunc = (o, e) => field.SetValue(o, e.DateTime);
                        }
                    }
                    else if (typeof(DateTimeOffset?).IsAssignableFrom(memberValueType))
                    {
                        if (property != null)
                        {
                            getEntityPropertyFunc = o => EntityProperty.GeneratePropertyForDateTimeOffset((DateTimeOffset?)property.GetValue(o));
                            setObjectPropertyFunc = (o, e) => property.SetValue(o, e.DateTimeOffsetValue);
                        }
                        else
                        {
                            getEntityPropertyFunc = o => EntityProperty.GeneratePropertyForDateTimeOffset((DateTimeOffset?)field.GetValue(o));
                            setObjectPropertyFunc = (o, e) => field.SetValue(o, e.DateTimeOffsetValue);
                        }
                    }
                    else if (typeof(Guid?).IsAssignableFrom(memberValueType))
                    {
                        if (property != null)
                        {
                            getEntityPropertyFunc = o => EntityProperty.GeneratePropertyForGuid((Guid?)property.GetValue(o));
                            setObjectPropertyFunc = (o, e) => property.SetValue(o, e.GuidValue);
                        }
                        else
                        {
                            getEntityPropertyFunc = o => EntityProperty.GeneratePropertyForGuid((Guid?)field.GetValue(o));
                            setObjectPropertyFunc = (o, e) => field.SetValue(o, e.GuidValue);
                        }
                    }
                    else if (typeof(double?).IsAssignableFrom(memberValueType))
                    {
                        if (property != null)
                        {
                            getEntityPropertyFunc = o => EntityProperty.GeneratePropertyForDouble((double?)property.GetValue(o));
                            setObjectPropertyFunc = (o, e) => property.SetValue(o, e.DoubleValue);
                        }
                        else
                        {
                            getEntityPropertyFunc = o => EntityProperty.GeneratePropertyForDouble((double?)field.GetValue(o));
                            setObjectPropertyFunc = (o, e) => field.SetValue(o, e.DoubleValue);
                        }
                    }
                    else if (typeof(byte[]).IsAssignableFrom(memberValueType))
                    {
                        if (property != null)
                        {
                            getEntityPropertyFunc = o => EntityProperty.GeneratePropertyForByteArray((byte[])property.GetValue(o));
                            setObjectPropertyFunc = (o, e) => property.SetValue(o, e.BinaryValue);
                        }
                        else
                        {
                            getEntityPropertyFunc = o => EntityProperty.GeneratePropertyForByteArray((byte[])field.GetValue(o));
                            setObjectPropertyFunc = (o, e) => field.SetValue(o, e.BinaryValue);
                        }
                    }
                    else // assume a serializeable object
                    {
                        getEntityPropertyFunc = o =>
                        {
                            object value = property != null?property.GetValue(o) : field.GetValue(o);

                            string json = value != null?JsonConvert.SerializeObject(value) : null;

                            return(EntityProperty.GeneratePropertyForString(json));
                        };

                        setObjectPropertyFunc = (o, e) =>
                        {
                            string json  = e.StringValue;
                            object value = json != null?JsonConvert.DeserializeObject(json, memberValueType) : null;

                            if (property != null)
                            {
                                property.SetValue(o, value);
                            }
                            else
                            {
                                field.SetValue(o, value);
                            }
                        };
                    }

                    propertyConverters.Add(new PropertyConverter(propertyName, getEntityPropertyFunc, setObjectPropertyFunc));
                }

                type = type.BaseType;
            }

            return(propertyConverters);
        }
Ejemplo n.º 2
0
        public override IDictionary <string, EntityProperty> WriteEntity(OperationContext operationContext)
        {
            var properties = new Dictionary <string, EntityProperty>();

            foreach (var getter in Getters)
            {
                var value = getter.Value.Item2(Entity);
                if (value == null)
                {
                    continue;
                }
                var            type           = getter.Value.Item1;
                EntityProperty entityProperty = null;
                if (type == typeof(bool) || type == typeof(bool?))
                {
                    entityProperty = EntityProperty.GeneratePropertyForBool((bool?)value);
                }
                else if (type == typeof(int) || type == typeof(int?))
                {
                    entityProperty = EntityProperty.GeneratePropertyForInt((int?)value);
                }
                else if (type == typeof(long) || type == typeof(long?))
                {
                    entityProperty = EntityProperty.GeneratePropertyForLong((long?)value);
                }
                else if (type == typeof(double) || type == typeof(double?))
                {
                    entityProperty = EntityProperty.GeneratePropertyForDouble((double?)value);
                }
                else if (type == typeof(float) || type == typeof(float?))
                {
                    entityProperty = EntityProperty.GeneratePropertyForDouble((float?)value);
                }
                else if (type == typeof(DateTime) || type == typeof(DateTime?))
                {
                    entityProperty = EntityProperty.GeneratePropertyForDateTimeOffset((DateTime?)value);
                }
                else if (type == typeof(DateTimeOffset) || type == typeof(DateTimeOffset?))
                {
                    entityProperty = EntityProperty.GeneratePropertyForDateTimeOffset((DateTimeOffset?)value);
                }
                else if (type == typeof(Guid) || type == typeof(Guid?))
                {
                    entityProperty = EntityProperty.GeneratePropertyForGuid((Guid?)value);
                }
                else if (type == typeof(byte[]))
                {
                    entityProperty = EntityProperty.GeneratePropertyForByteArray(value as byte[]);
                }
                else if (type == typeof(string))
                {
                    entityProperty = EntityProperty.GeneratePropertyForString(value as string);
                }

                if (entityProperty != null)
                {
                    properties[getter.Key] = entityProperty;
                }
            }
            return(properties);
        }
Ejemplo n.º 3
0
        public void Log <TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func <TState, Exception, string> formatter)
        {
            if (!IsEnabled(logLevel))
            {
                return;
            }

            if (formatter == null)
            {
                throw new ArgumentNullException(nameof(formatter));
            }

            var    message            = formatter(state, exception);
            string exceptionText      = exception?.ToString();
            bool   hasMessageOverflow = message.Length > overflowThreshold;

            var properties = new Dictionary <string, EntityProperty>
            {
                ["LogLevel"]            = EntityProperty.GeneratePropertyForString(logLevel.ToString()),
                ["Message"]             = EntityProperty.GeneratePropertyForString(hasMessageOverflow ? message.Substring(0, overflowThreshold) : message),
                ["ExceptionText"]       = EntityProperty.GeneratePropertyForString(exceptionText),
                ["EventId"]             = EntityProperty.GeneratePropertyForInt(eventId.Id),
                ["EventName"]           = EntityProperty.GeneratePropertyForString(eventId.Name),
                ["Date"]                = EntityProperty.GeneratePropertyForDateTimeOffset(DateTimeOffset.Now),
                ["LoggerName"]          = EntityProperty.GeneratePropertyForString(this.Name),
                ["IsMessageOverflowed"] = EntityProperty.GeneratePropertyForBool(hasMessageOverflow),
            };

            string requestId = null;
            var    current   = AzureScope.Current;

            while (current != null)
            {
                foreach (var item in current.Values)
                {
                    properties.Add($"Scope{current.StateName}{item.Key}", EntityProperty.CreateEntityPropertyFromObject(item.Value));
                    if (item.Key == "RequestId")
                    {
                        requestId = (string)item.Value;
                    }
                }

                current = current.Parent;
            }

            properties["RequestId"] = EntityProperty.GeneratePropertyForString(requestId);

            var id        = timeBasedId.NewId();
            var partition = (requestId ?? id).Substring(0, 5);

            if (message != null || exceptionText != null)
            {
                var entity = new DynamicTableEntity(
                    partition,
                    id, null, properties);

                this.sink.Post(entity);
                if (hasMessageOverflow)
                {
                    this.overflowSink.Post(new KeyValuePair <string, string>(id, message));
                }
            }
        }