Skip to content

Commit

Permalink
Use System.Text.Json as the default serializer (#504) (#541)
Browse files Browse the repository at this point in the history
Co-authored-by: Sébastien Ros <[email protected]>
  • Loading branch information
MikeAlhayek and sebastienros authored May 2, 2024
1 parent e8bafa2 commit a906437
Show file tree
Hide file tree
Showing 11 changed files with 154 additions and 43 deletions.
2 changes: 1 addition & 1 deletion src/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<PropertyGroup>
<Copyright>Sebastien Ros</Copyright>
<Authors>Sebastien Ros</Authors>
<TargetFrameworks>net6.0</TargetFrameworks>
<TargetFrameworks>net7.0</TargetFrameworks>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<DebugType>portable</DebugType>
<PackageProjectUrl>https://github.com/sebastienros/yessql</PackageProjectUrl>
Expand Down
7 changes: 0 additions & 7 deletions src/YesSql.Abstractions/IContentSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,5 @@ public interface IContentSerializer
/// <param name="type">The type of the object to deserialize.</param>
/// <returns>The deserialized object.</returns>
object Deserialize(string content, Type type);

/// <summary>
/// Deserializes an object to a <c>dynamic</c> instance.
/// </summary>
/// <param name="content">The <see cref="String" /> instance representing the object to deserialize.</param>
/// <returns>The deserialized object.</returns>
dynamic DeserializeDynamic(string content);
}
}
2 changes: 1 addition & 1 deletion src/YesSql.Core/Configuration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public Configuration()
{
IdentifierAccessorFactory = new PropertyAccessorFactory("Id");
VersionAccessorFactory = new PropertyAccessorFactory("Version");
ContentSerializer = new JsonContentSerializer();
ContentSerializer = new DefaultContentSerializer();
IdGenerator = new DefaultIdGenerator();
IsolationLevel = IsolationLevel.ReadCommitted;
TablePrefix = "";
Expand Down
34 changes: 34 additions & 0 deletions src/YesSql.Core/Serialization/DefaultContentSerializer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using System;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace YesSql.Serialization
{
public class DefaultContentSerializer : IContentSerializer
{
private readonly JsonSerializerOptions _options;

public DefaultContentSerializer()
{
_options = new();
_options.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
_options.Converters.Add(UtcDateTimeJsonConverter.Instance);
_options.Converters.Add(DynamicJsonConverter.Instance);
}

public DefaultContentSerializer(JsonSerializerOptions options)
{
_options = options;
}

public object Deserialize(string content, Type type)
{
return JsonSerializer.Deserialize(content, type, _options);
}

public string Serialize(object item)
{
return JsonSerializer.Serialize(item, _options);
}
}
}
82 changes: 82 additions & 0 deletions src/YesSql.Core/Serialization/DynamicJsonConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace YesSql.Serialization
{
public class DynamicJsonConverter : JsonConverter<object>
{
public static readonly DynamicJsonConverter Instance = new();

public override object Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
switch (reader.TokenType)
{
case JsonTokenType.Null:
return null;
case JsonTokenType.False:
return false;
case JsonTokenType.True:
return true;
case JsonTokenType.String:
return reader.GetString();
case JsonTokenType.Number:
{
if (reader.TryGetInt32(out var i))
return i;
if (reader.TryGetInt64(out var l))
return l;
// BigInteger could be added here.
if (reader.TryGetDouble(out var d))
return d;

throw new JsonException("Cannot parse number");
}
case JsonTokenType.StartArray:
{
var list = new List<object>();
while (reader.Read())
{
switch (reader.TokenType)
{
default:
list.Add(Read(ref reader, typeof(object), options));
break;
case JsonTokenType.EndArray:
return list;
}
}
throw new JsonException();
}
case JsonTokenType.StartObject:
IDictionary<string, object> dict = new ExpandoObject();
while (reader.Read())
{
switch (reader.TokenType)
{
case JsonTokenType.EndObject:
return dict;
case JsonTokenType.PropertyName:
var key = reader.GetString();
reader.Read();
dict[key] = Read(ref reader, typeof(object), options);
break;
default:
throw new JsonException();
}
}
throw new JsonException();
default:
throw new JsonException(string.Format("Unknown token {0}", reader.TokenType));
}
}

public override void Write(
Utf8JsonWriter writer,
object objectToWrite,
JsonSerializerOptions options) =>
JsonSerializer.Serialize(writer, objectToWrite, objectToWrite.GetType(), options);
}
}
30 changes: 0 additions & 30 deletions src/YesSql.Core/Serialization/JsonContentSerializer.cs

This file was deleted.

29 changes: 29 additions & 0 deletions src/YesSql.Core/Serialization/UtcDateTimeJsonConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System;
using System.Diagnostics;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace YesSql.Serialization
{
public class UtcDateTimeJsonConverter : JsonConverter<DateTime>
{
public static readonly UtcDateTimeJsonConverter Instance = new();

public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
Debug.Assert(typeToConvert == typeof(DateTime));

if (!reader.TryGetDateTime(out DateTime value))
{
value = DateTime.UtcNow;
}

return value;
}

public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.ToUniversalTime());
}
}
}
1 change: 0 additions & 1 deletion src/YesSql.Core/YesSql.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

<ItemGroup>
<PackageReference Include="Dapper.StrongName" />
<PackageReference Include="Newtonsoft.Json" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
</ItemGroup>

Expand Down
4 changes: 2 additions & 2 deletions test/YesSql.Tests/Models/Animal.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
using System.Runtime.Serialization;
using System.Text.Json.Serialization;

namespace YesSql.Tests.Models
{
public class Animal
{
public string Name { get; set; }

[IgnoreDataMember]
[JsonIgnore]
public string Color { get; set; }
}
}
4 changes: 4 additions & 0 deletions test/YesSql.Tests/Models/Drawing.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Text.Json.Serialization;

namespace YesSql.Tests.Models
{
Expand All @@ -12,6 +13,9 @@ public Drawing()
public IList<Shape> Shapes { get; set; }
}

[JsonPolymorphic]
[JsonDerivedType(typeof(Square), nameof(Square))]
[JsonDerivedType(typeof(Circle), nameof(Circle))]
public abstract class Shape
{
public long Id { get; set; }
Expand Down
2 changes: 1 addition & 1 deletion test/YesSql.Tests/YesSql.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net6.0;net7.0;net8.0</TargetFrameworks>
<TargetFrameworks>net7.0;net8.0</TargetFrameworks>
<LangVersion>latest</LangVersion>
<AssemblyName>YesSql.Tests</AssemblyName>
<PackageId>YesSql.Tests</PackageId>
Expand Down

0 comments on commit a906437

Please sign in to comment.