Skip to content

♻️ refactor: Newtonsoft.Json to System.Text.Json #74

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Collections.Generic;
using System.Text.Json;
using Revo.DataAccess.Entities;
using Revo.Domain.ReadModel;

Expand All @@ -10,7 +10,7 @@
public class EntityAttributeData : EntityReadModel
{
private string attributeValueMapJson;
private JObject attributeValueMap;
private Dictionary<string, dynamic> attributeValueMap = [];

public EntityAttributeData(Guid id, Guid? aggregateId, Guid? entityId)
{
Expand All @@ -28,38 +28,42 @@

public string AttributeValueMapJson
{
get { return attributeValueMapJson ?? (attributeValueMapJson = attributeValueMap?.ToString(Formatting.None) ?? "{}"); }
get
{
return attributeValueMapJson ??= JsonSerializer.Serialize(attributeValueMap);
}

private set
{
attributeValueMapJson = value;
attributeValueMap = JObject.Parse(attributeValueMapJson);
if (string.IsNullOrWhiteSpace(attributeValueMapJson))
{
attributeValueMap = [];

Check warning on line 41 in Extensions/Revo.Extensions.History/ChangeTracking/Model/EntityAttributeData.cs

View check run for this annotation

Codecov / codecov/patch

Extensions/Revo.Extensions.History/ChangeTracking/Model/EntityAttributeData.cs#L41

Added line #L41 was not covered by tests
}
else
{
attributeValueMap = JsonSerializer.Deserialize<Dictionary<string, dynamic>>(attributeValueMapJson);

Check warning on line 45 in Extensions/Revo.Extensions.History/ChangeTracking/Model/EntityAttributeData.cs

View check run for this annotation

Codecov / codecov/patch

Extensions/Revo.Extensions.History/ChangeTracking/Model/EntityAttributeData.cs#L45

Added line #L45 was not covered by tests
}
}
}

public bool TryGetAttributeValue<T>(string attributeName, out T value)
{
JToken token = null;
if (attributeValueMap?.TryGetValue(attributeName, out token) ?? false)
if (attributeValueMap.TryGetValue(attributeName, out dynamic token))
{
value = (T)(dynamic)token;
value = (T)token;
return true;
}
else
{
value = default(T);
value = default;
return false;
}
}

public void SetAttributeValue<T>(string attributeName, T attributeValue)
{
if (attributeValueMap == null)
{
attributeValueMap = new JObject();
}

attributeValueMap[attributeName] = attributeValue != null ? JToken.FromObject(attributeValue) : JValue.CreateNull();
attributeValueMap[attributeName] = attributeValue;
attributeValueMapJson = null;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using System;
using Newtonsoft.Json;
using System.Text.Json;
using Revo.Extensions.History.ChangeTracking.Model;

namespace Revo.Extensions.History.ChangeTracking
Expand All @@ -15,8 +15,8 @@ public TrackedChangeRecordConverter(IChangeDataTypeCache changeDataTypeCache)

public TrackedChange FromRecord(TrackedChangeRecord record)
{
Type changeDataType = changeDataTypeCache.GetClrChangeDataType(record.ChangeDataClassName);
ChangeData changeData = (ChangeData)JsonConvert.DeserializeObject(record.ChangeDataJson, changeDataType);
var changeDataType = changeDataTypeCache.GetClrChangeDataType(record.ChangeDataClassName);
var changeData = (ChangeData)JsonSerializer.Deserialize(record.ChangeDataJson, changeDataType);

return new TrackedChange(
record.Id,
Expand All @@ -41,7 +41,7 @@ public TrackedChangeRecord ToRecord(TrackedChange change)
AggregateClassId = change.AggregateClassId,
AggregateId = change.AggregateId,
ChangeDataClassName = changeDataTypeCache.GetChangeDataTypeName(change.ChangeData.GetType()),
ChangeDataJson = JsonConvert.SerializeObject(change.ChangeData),
ChangeDataJson = JsonSerializer.Serialize(change.ChangeData, change.ChangeData.GetType()),
ChangeTime = change.ChangeTime,
EntityClassId = change.EntityClassId,
EntityId = change.EntityId
Expand Down
36 changes: 11 additions & 25 deletions Extensions/Revo.Extensions.Notifications/NotificationSerializer.cs
Original file line number Diff line number Diff line change
@@ -1,51 +1,37 @@
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Revo.Extensions.Notifications
{
public class NotificationSerializer : INotificationSerializer
public class NotificationSerializer(INotificationTypeCache notificationTypeCache) : INotificationSerializer
{
private static readonly JsonSerializerSettings JsonSerializerSettings = new JsonSerializerSettings
private static readonly JsonSerializerOptions JsonSerializerSettings = new()

Check warning on line 8 in Extensions/Revo.Extensions.Notifications/NotificationSerializer.cs

View check run for this annotation

Codecov / codecov/patch

Extensions/Revo.Extensions.Notifications/NotificationSerializer.cs#L8

Added line #L8 was not covered by tests
{
ContractResolver = new DefaultContractResolver
{
NamingStrategy = new CamelCaseNamingStrategy
{
ProcessDictionaryKeys = false
}
},
Formatting = Formatting.None
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,

Check warning on line 10 in Extensions/Revo.Extensions.Notifications/NotificationSerializer.cs

View check run for this annotation

Codecov / codecov/patch

Extensions/Revo.Extensions.Notifications/NotificationSerializer.cs#L10

Added line #L10 was not covered by tests
};

static NotificationSerializer()
{
JsonSerializerSettings.Converters.Add(new StringEnumConverter());
JsonSerializerSettings.Converters.Add(new JsonStringEnumConverter());

Check warning on line 15 in Extensions/Revo.Extensions.Notifications/NotificationSerializer.cs

View check run for this annotation

Codecov / codecov/patch

Extensions/Revo.Extensions.Notifications/NotificationSerializer.cs#L15

Added line #L15 was not covered by tests
}

private readonly INotificationTypeCache notificationTypeCache;

public NotificationSerializer(INotificationTypeCache notificationTypeCache)
{
this.notificationTypeCache = notificationTypeCache;
}
private readonly INotificationTypeCache notificationTypeCache = notificationTypeCache;

Check warning on line 18 in Extensions/Revo.Extensions.Notifications/NotificationSerializer.cs

View check run for this annotation

Codecov / codecov/patch

Extensions/Revo.Extensions.Notifications/NotificationSerializer.cs#L18

Added line #L18 was not covered by tests

public SerializedNotification ToJson(INotification notification)
{
SerializedNotification serialized = new SerializedNotification()
var serialized = new SerializedNotification()

Check warning on line 22 in Extensions/Revo.Extensions.Notifications/NotificationSerializer.cs

View check run for this annotation

Codecov / codecov/patch

Extensions/Revo.Extensions.Notifications/NotificationSerializer.cs#L22

Added line #L22 was not covered by tests
{
NotificationClassName = notificationTypeCache.GetNotificationTypeName(notification.GetType()),
NotificationJson = JsonConvert.SerializeObject(notification, JsonSerializerSettings)
NotificationJson = JsonSerializer.Serialize(notification, notification.GetType(), JsonSerializerSettings)

Check warning on line 25 in Extensions/Revo.Extensions.Notifications/NotificationSerializer.cs

View check run for this annotation

Codecov / codecov/patch

Extensions/Revo.Extensions.Notifications/NotificationSerializer.cs#L25

Added line #L25 was not covered by tests
};

return serialized;
}

public INotification FromJson(SerializedNotification serializedNotification)
{
Type notificationType = notificationTypeCache.GetClrNotificationType(serializedNotification.NotificationClassName);
return (INotification)JsonConvert.DeserializeObject(serializedNotification.NotificationJson, notificationType, JsonSerializerSettings);
var notificationType = notificationTypeCache.GetClrNotificationType(serializedNotification.NotificationClassName);
return (INotification)JsonSerializer.Deserialize(serializedNotification.NotificationJson, notificationType, JsonSerializerSettings);

Check warning on line 34 in Extensions/Revo.Extensions.Notifications/NotificationSerializer.cs

View check run for this annotation

Codecov / codecov/patch

Extensions/Revo.Extensions.Notifications/NotificationSerializer.cs#L33-L34

Added lines #L33 - L34 were not covered by tests
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System;
using Newtonsoft.Json.Linq;
using System.Collections.Generic;
using System.Text.Json;

using NSubstitute;
using Revo.Extensions.History.ChangeTracking;
using Revo.Extensions.History.ChangeTracking.Model;
Expand Down Expand Up @@ -67,7 +69,7 @@ public void ToRecord_Result()
Assert.Equal(change.EntityId, record.EntityId);
Assert.Equal(change.EntityClassId, record.EntityClassId);
Assert.Equal("TestChangeData", record.ChangeDataClassName);
Assert.Equal("bar", JObject.Parse(record.ChangeDataJson)["Foo"]);
Assert.Equal("bar", JsonSerializer.Deserialize<Dictionary<string, string>>(record.ChangeDataJson)["Foo"]);
Assert.Equal(change.ChangeTime, record.ChangeTime);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using System;
using Newtonsoft.Json;
using System.Text.Json;
using Revo.Core.Configuration;

namespace Revo.EF6.Configuration
Expand All @@ -14,6 +14,6 @@
public bool UseEventSourcedAggregateStore { get; set; }
public bool UseCrudAggregateStore { get; set; }

public Func<JsonSerializerSettings, JsonSerializerSettings> CustomizeEventJsonSerializer { get; set; } = settings => settings;
public Func<JsonSerializerOptions, JsonSerializerOptions> CustomizeEventJsonSerializer { get; set; } = settings => settings;

Check warning on line 17 in Providers/EF6/Revo.EF6/Configuration/EF6InfrastructureConfigurationSection.cs

View check run for this annotation

Codecov / codecov/patch

Providers/EF6/Revo.EF6/Configuration/EF6InfrastructureConfigurationSection.cs#L17

Added line #L17 was not covered by tests
}
}
6 changes: 3 additions & 3 deletions Providers/EF6/Revo.EF6/Events/EF6EventsModule.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using System;
using Newtonsoft.Json;
using System.Text.Json;
using Ninject.Modules;
using Revo.Core.Core;
using Revo.DataAccess.Entities;
Expand All @@ -15,9 +15,9 @@
[AutoLoadModule(false)]
public class EF6AsyncEventsModule : NinjectModule
{
private readonly Func<JsonSerializerSettings, JsonSerializerSettings> customizeEventJsonSerializer;
private readonly Func<JsonSerializerOptions, JsonSerializerOptions> customizeEventJsonSerializer;

public EF6AsyncEventsModule(Func<JsonSerializerSettings, JsonSerializerSettings> customizeEventJsonSerializer)
public EF6AsyncEventsModule(Func<JsonSerializerOptions, JsonSerializerOptions> customizeEventJsonSerializer)

Check warning on line 20 in Providers/EF6/Revo.EF6/Events/EF6EventsModule.cs

View check run for this annotation

Codecov / codecov/patch

Providers/EF6/Revo.EF6/Events/EF6EventsModule.cs#L20

Added line #L20 was not covered by tests
{
this.customizeEventJsonSerializer = customizeEventJsonSerializer;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using System;
using Newtonsoft.Json;
using System.Text.Json;
using Revo.Core.Configuration;

namespace Revo.EFCore.Configuration
Expand All @@ -14,6 +14,6 @@
public bool UseEventSourcedAggregateStore { get; set; }
public bool UseCrudAggregateStore { get; set; }

public Func<JsonSerializerSettings, JsonSerializerSettings> CustomizeEventJsonSerializer { get; set; } = settings => settings;
public Func<JsonSerializerOptions, JsonSerializerOptions> CustomizeEventJsonSerializer { get; set; } = settings => settings;

Check warning on line 17 in Providers/EFCore/Revo.EFCore/Configuration/EFCoreInfrastructureConfigurationSection.cs

View check run for this annotation

Codecov / codecov/patch

Providers/EFCore/Revo.EFCore/Configuration/EFCoreInfrastructureConfigurationSection.cs#L17

Added line #L17 was not covered by tests
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

foreach (var property in entity.GetProperties())
{
property.SetColumnName(property.GetColumnBaseName().ToLowerInvariant());
property.SetColumnName(property.GetColumnName().ToLowerInvariant());

Check warning on line 22 in Providers/EFCore/Revo.EFCore/DataAccess/Conventions/LowerCaseConvention.cs

View check run for this annotation

Codecov / codecov/patch

Providers/EFCore/Revo.EFCore/DataAccess/Conventions/LowerCaseConvention.cs#L22

Added line #L22 was not covered by tests
}

foreach (var key in entity.GetKeys())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
{
foreach (var property in entity.GetProperties())
{
if (property.DeclaringEntityType != entity)
if (property.DeclaringType != entity)
{
continue;
}
Expand All @@ -64,7 +64,7 @@
?? property.FieldInfo?.DeclaringType;
TablePrefixAttribute clrTypePrefixAttribute;
if (clrDeclaringType != null
&& property.DeclaringEntityType.ClrType != clrDeclaringType
&& property.DeclaringType.ClrType != clrDeclaringType

Check warning on line 67 in Providers/EFCore/Revo.EFCore/DataAccess/Conventions/PrefixConvention.cs

View check run for this annotation

Codecov / codecov/patch

Providers/EFCore/Revo.EFCore/DataAccess/Conventions/PrefixConvention.cs#L67

Added line #L67 was not covered by tests
&& (clrTypePrefixAttribute = GetTablePrefixAttribute(clrDeclaringType)) != null) //this might happen e.g. if clrDeclaringType is abstract but not
{
propertyNamespacePrefix = clrTypePrefixAttribute.NamespacePrefix;
Expand All @@ -73,12 +73,12 @@

if (propertyColumnPrefix?.Length > 0)
{
property.SetColumnName($"{propertyColumnPrefix}_{property.GetColumnBaseName()}");
property.SetColumnName($"{propertyColumnPrefix}_{property.GetColumnName()}");

Check warning on line 76 in Providers/EFCore/Revo.EFCore/DataAccess/Conventions/PrefixConvention.cs

View check run for this annotation

Codecov / codecov/patch

Providers/EFCore/Revo.EFCore/DataAccess/Conventions/PrefixConvention.cs#L76

Added line #L76 was not covered by tests
}

if (propertyNamespacePrefix?.Length > 0)
{
property.SetColumnName($"{propertyNamespacePrefix}_{property.GetColumnBaseName()}");
property.SetColumnName($"{propertyNamespacePrefix}_{property.GetColumnName()}");

Check warning on line 81 in Providers/EFCore/Revo.EFCore/DataAccess/Conventions/PrefixConvention.cs

View check run for this annotation

Codecov / codecov/patch

Providers/EFCore/Revo.EFCore/DataAccess/Conventions/PrefixConvention.cs#L81

Added line #L81 was not covered by tests
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
{
foreach (var property in entity.GetProperties())
{
property.SetColumnName(ToSnakeCase(property.GetColumnBaseName()));
property.SetColumnName(ToSnakeCase(property.GetColumnName()));

Check warning on line 18 in Providers/EFCore/Revo.EFCore/DataAccess/Conventions/SnakeCaseColumnNamesConvention.cs

View check run for this annotation

Codecov / codecov/patch

Providers/EFCore/Revo.EFCore/DataAccess/Conventions/SnakeCaseColumnNamesConvention.cs#L18

Added line #L18 was not covered by tests
}

foreach (var key in entity.GetKeys())
Expand Down
2 changes: 1 addition & 1 deletion Providers/EFCore/Revo.EFCore/Domain/ReadModelConvention.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
var originalEntity = modelBuilder.Model.GetEntityTypes().FirstOrDefault(x => x.ClrType == attr.EntityType)
?? throw new InvalidOperationException($"Cannot map {entity.ClrType} as ReadModelForEntity for {attr.EntityType} because the latter is not part of the model.");

entity.FindProperty("Id").SetColumnName(originalEntity.FindProperty("Id").GetColumnBaseName());
entity.FindProperty("Id").SetColumnName(originalEntity.FindProperty("Id").GetColumnName());

Check warning on line 41 in Providers/EFCore/Revo.EFCore/Domain/ReadModelConvention.cs

View check run for this annotation

Codecov / codecov/patch

Providers/EFCore/Revo.EFCore/Domain/ReadModelConvention.cs#L41

Added line #L41 was not covered by tests
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions Providers/EFCore/Revo.EFCore/Events/EFCoreEventsModule.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using System;
using Newtonsoft.Json;
using System.Text.Json;
using Ninject.Modules;
using Revo.Core.Core;
using Revo.Infrastructure;
Expand All @@ -13,9 +13,9 @@
[AutoLoadModule(false)]
public class EFCoreAsyncEventsModule : NinjectModule
{
private readonly Func<JsonSerializerSettings, JsonSerializerSettings> customizeEventJsonSerializer;
private readonly Func<JsonSerializerOptions, JsonSerializerOptions> customizeEventJsonSerializer;

public EFCoreAsyncEventsModule(Func<JsonSerializerSettings, JsonSerializerSettings> customizeEventJsonSerializer)
public EFCoreAsyncEventsModule(Func<JsonSerializerOptions, JsonSerializerOptions> customizeEventJsonSerializer)

Check warning on line 18 in Providers/EFCore/Revo.EFCore/Events/EFCoreEventsModule.cs

View check run for this annotation

Codecov / codecov/patch

Providers/EFCore/Revo.EFCore/Events/EFCoreEventsModule.cs#L18

Added line #L18 was not covered by tests
{
this.customizeEventJsonSerializer = customizeEventJsonSerializer;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public async Task ProjectsBeforeCommit()

await sut.OnBeforeCommitAsync();

projectionSubSystem.Received(1).ExecuteProjectionsAsync(
await projectionSubSystem.Received(1).ExecuteProjectionsAsync(
Arg.Is<IReadOnlyCollection<IEventMessage<DomainAggregateEvent>>>(
evs => evs.SequenceEqual(events)),
unitOfWork,
Expand All @@ -54,15 +54,15 @@ public async Task ProjectsOnlyAdditionalEvents()
events.Add(new TestEvent().ToMessageDraft());
await sut.OnBeforeCommitAsync();

projectionSubSystem.ReceivedWithAnyArgs(2).ExecuteProjectionsAsync(null, null, null);
await projectionSubSystem.ReceivedWithAnyArgs(2).ExecuteProjectionsAsync(null, null, null);

projectionSubSystem.Received(1).ExecuteProjectionsAsync(
await projectionSubSystem.Received(1).ExecuteProjectionsAsync(
Arg.Is<IReadOnlyCollection<IEventMessage<DomainAggregateEvent>>>(
evs => evs.SequenceEqual(new[] { events[0] })),
unitOfWork,
Arg.Is<EFCoreEventProjectionOptions>(x => x.IsSynchronousProjection));

projectionSubSystem.Received(1).ExecuteProjectionsAsync(
await projectionSubSystem.Received(1).ExecuteProjectionsAsync(
Arg.Is<IReadOnlyCollection<IEventMessage<DomainAggregateEvent>>>(
evs => evs.SequenceEqual(new[] { events[1] })),
unitOfWork,
Expand All @@ -79,7 +79,7 @@ public async Task ProjectsAgainAfterCommitSucceeded()
await sut.OnCommitSucceededAsync();
await sut.OnBeforeCommitAsync();

projectionSubSystem.Received(2).ExecuteProjectionsAsync(
await projectionSubSystem.Received(2).ExecuteProjectionsAsync(
Arg.Is<IReadOnlyCollection<IEventMessage<DomainAggregateEvent>>>(
evs => evs.SequenceEqual(events)),
unitOfWork,
Expand All @@ -96,7 +96,7 @@ public async Task ProjectsAgainAfterCommitFailed()
await sut.OnCommitFailedAsync();
await sut.OnBeforeCommitAsync();

projectionSubSystem.Received(2).ExecuteProjectionsAsync(
await projectionSubSystem.Received(2).ExecuteProjectionsAsync(
Arg.Is<IReadOnlyCollection<IEventMessage<DomainAggregateEvent>>>(
evs => evs.SequenceEqual(events)),
unitOfWork,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public async Task PublishAsync_Event()

await sut.PublishAsync(event1);

pubSub.Received(1).PublishAsync(Arg.Is<IEventMessage<Event1>>(
await pubSub.Received(1).PublishAsync(Arg.Is<IEventMessage<Event1>>(
x => x.GetType().IsConstructedGenericType
&& x.GetType().GetGenericTypeDefinition() == typeof(EventMessage<>)
&& x.Event == event1
Expand All @@ -56,7 +56,7 @@ public async Task PublishAsync_EventMessage()

await sut.PublishAsync(message);

pubSub.Received(1).PublishAsync(Arg.Is<IEventMessage<Event1>>(
await pubSub.Received(1).PublishAsync(Arg.Is<IEventMessage<Event1>>(
x => x.GetType().IsConstructedGenericType
&& x.GetType().GetGenericTypeDefinition() == typeof(EventMessage<>)
&& x.Event == event1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public async Task HandleMessage()

await sut.HandleMessageAsync(eventMessage);

eventBus.Received(1).PublishAsync(eventMessage);
await eventBus.Received(1).PublishAsync(eventMessage);
currentTaskContext.Should().NotBeNull();
currentTaskContext.Should().NotBe(prevTaskContext);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public async Task HandleAsync()
var message = (IEventMessage<Event2>) EventMessage.FromEvent(new Event2(), new Dictionary<string, string>());
await sut.HandleAsync(message, CancellationToken.None);

easyNetQBus.Received(1).PublishAsync<Event1>(message);
await easyNetQBus.Received(1).PublishAsync<Event1>(message);
}

private class Event1 : IEvent
Expand Down
Loading
Loading