public IValueContainer Decompose(object value) { var ex = (Exception)value; return(new ExceptionContainer { Type = _typeSerializerHelper.GetTypeSerializationInfo(ex.GetType()).ToString(), Message = ex.Message, InnerException = (ex is AggregateException) ? null : ex.InnerException, InnerExceptions = (ex is AggregateException aggregateException) ? aggregateException.InnerExceptions.ToArray() : null, StackTrace = ex.StackTrace });
public IValueContainer Decompose(object value) { #warning Add support for multi-projection. Need to know the variable/result type - a bigger serializer problem :( Also possibly need to know if it's a cross-domain derialization to keep the entity instance. var projetionInterface = value.GetType().GetInterfaces() .First(i => KnownEntityProjectionInterfaces != null ? KnownEntityProjectionInterfaces.Contains(i) : EntityProjection.IsProjectionInterface(i)); var container = new EntityProjectionContainer { Type = _typeSerializerHelper.GetTypeSerializationInfo(projetionInterface).ToString(), Properties = new Dictionary <string, object>() }; #warning Add properties of base interface(s) foreach (var property in projetionInterface.GetProperties()) { container.Properties.Add(property.Name, property.GetValue(value)); } return(container); }
private void SerializeValue(string name, Type type, object value, IValueWriter writer, Type collectionItemType = null, int?index = null) { var valueInfo = new ValueInfo { Name = name, Index = index }; if (value != null) { type = value.GetType(); } var writeValueAsReference = false; if (value != null && !type.IsValueType() && type != typeof(string) && type != typeof(Uri)) { var objectId = _idGenerator.GetId(value, out var isFirstTime); if (_specialIds.TryGetValue(objectId, out var specialId)) { valueInfo.SpecialId = specialId; writeValueAsReference = true; } else { valueInfo.ReferenceId = objectId; writeValueAsReference = !isFirstTime; } } if (value is Type valueAsType) { valueInfo.Type = _typeSerializerHelper.GetTypeSerializationInfo(valueAsType); type = typeof(Type); } if (writeValueAsReference) { // Reset other fields, because they don't need to be written. valueInfo.Type = null; valueInfo.ItemType = null; valueInfo.ItemCount = null; writer.WriteStartValue(valueInfo); writer.WriteEndValue(); } else if (value == null) { writer.WriteStartValue(valueInfo); writer.WriteValue(null); writer.WriteEndValue(); } else if (writer.CanWriteValueWithoutTypeInfo(type)) { writer.WriteStartValue(valueInfo); writer.WriteValue(value); writer.WriteEndValue(); } else if (type.IsEnum()) { writer.WriteStartValue(valueInfo); value = Convert.ChangeType(value, type.GetEnumUnderlyingType()); writer.WriteValue(value); writer.WriteEndValue(); } #warning Treat other types of collections as arrays else if (type.IsArray) { var items = (IList)value; var itemType = type.GetElementType(); valueInfo.IsCollection = true; #warning Write collection type //valueInfo.Type = valueInfo.ItemType = itemType == typeof(object) || itemType == collectionItemType ? null : _typeSerializerHelper.GetTypeSerializationInfo(itemType); valueInfo.ItemCount = items.Count; writer.WriteStartValue(valueInfo); var itemIndex = 0; foreach (var item in items) { SerializeValue(null, item?.GetType(), item, writer, collectionItemType: itemType, index: itemIndex++); } writer.WriteEndValue(); } else if (value is IValueContainer valueAsContainer) { writer.WriteStartValue(valueInfo); if (valueAsContainer.GetCount() == 0) { writer.WriteValue(null); } else { SerializeValueContainer(valueAsContainer, writer); } writer.WriteEndValue(); } else { if (!TryDecomposeValue(type, value, out var typeInfo, out var nestedContainer)) { throw new UnserializableTypeException(type); } valueInfo.Type = typeInfo; writer.WriteStartValue(valueInfo); SerializeValueContainer(nestedContainer, writer); writer.WriteEndValue(); } }