Last active
November 13, 2020 11:35
-
-
Save egil/ac0974eeb2655cfe32e7fbecc08cbf3a to your computer and use it in GitHub Desktop.
Draft for EntityCosmosJsonConverter that avoids poluting domain objects with Cosmos specific properties
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
public abstract class Entity | |
{ | |
public Guid Id { get; set; } | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Reflection; | |
using System.Text.Json; | |
using System.Text.Json.Serialization; | |
public class EntityCosmosJsonConverter : JsonConverter<Entity> | |
{ | |
private readonly JsonSerializerOptions converterOptions; | |
public override bool CanConvert(Type typeToConvert) | |
=> typeof(Entity).IsAssignableFrom(typeToConvert); | |
public EntityCosmosJsonConverter(JsonSerializerOptions options) | |
{ | |
converterOptions = CopyOptionsExceptSelf(options); | |
} | |
public override Entity Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) | |
{ | |
var result = JsonSerializer.Deserialize(ref reader, typeToConvert, converterOptions) as Entity; | |
return result ?? throw new JsonException("TAAAADA"); | |
} | |
public override void Write(Utf8JsonWriter writer, Entity entity, JsonSerializerOptions options) | |
{ | |
var entityType = entity.GetType(); | |
writer.WriteStartObject(); | |
// Add cosmos specific fields | |
writer.WriteString("id", entity.Id); | |
writer.WriteString("pk", entityType.Name); | |
foreach (var propertyInfo in entityType.GetProperties(BindingFlags.Public | BindingFlags.Instance)) | |
{ | |
if (propertyInfo.Name.Equals("id", StringComparison.OrdinalIgnoreCase)) | |
continue; | |
if (!propertyInfo.CanWrite && options.IgnoreReadOnlyProperties) | |
continue; | |
var value = propertyInfo.GetValue(entity); | |
if (value is { } || !options.IgnoreNullValues) | |
{ | |
var propertyName = options.PropertyNamingPolicy?.ConvertName(propertyInfo.Name) ?? propertyInfo.Name; | |
writer.WritePropertyName(propertyName); | |
JsonSerializer.Serialize(writer, value, propertyInfo.PropertyType, converterOptions); | |
} | |
} | |
writer.WriteEndObject(); | |
} | |
private static JsonSerializerOptions CopyOptionsExceptSelf(JsonSerializerOptions options) | |
{ | |
var result = new JsonSerializerOptions | |
{ | |
AllowTrailingCommas = options.AllowTrailingCommas, | |
DefaultBufferSize = options.DefaultBufferSize, | |
DictionaryKeyPolicy = options.DictionaryKeyPolicy, | |
Encoder = options.Encoder, | |
IgnoreNullValues = options.IgnoreNullValues, | |
IgnoreReadOnlyProperties = options.IgnoreReadOnlyProperties, | |
MaxDepth = options.MaxDepth, | |
PropertyNameCaseInsensitive = options.PropertyNameCaseInsensitive, | |
PropertyNamingPolicy = options.PropertyNamingPolicy, | |
ReadCommentHandling = options.ReadCommentHandling, | |
WriteIndented = options.WriteIndented | |
}; | |
// Copy options but skip the adding this converter. | |
foreach (var converter in options.Converters) | |
{ | |
if (converter is EntityCosmosJsonConverter) | |
continue; | |
result.Converters.Add(converter); | |
} | |
return result; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"id": "3353613d-a173-4e25-b99c-092f35145d1d", | |
"pk": "Todo", | |
"name": "Remove Cosmos from entities", | |
"_rid": "EFNFAIGlGTwYAAAAAAAAAA==", | |
"_self": "dbs/EFNFAA==/colls/EFNFAIGlGTw=/docs/EFNFAIGlGTwYAAAAAAAAAA==/", | |
"_etag": "\"00000000-0000-0000-b8ed-658a050c01d6\"", | |
"_attachments": "attachments/", | |
"_ts": 1605183280 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment