Skip to content
This repository has been archived by the owner on Jan 16, 2024. It is now read-only.

Commit

Permalink
Add some custom converters as a hack to get serialization/deserializa…
Browse files Browse the repository at this point in the history
…tion working.

Upgrading to .NET 5.0 should fix this as it supports working with classes without default constructors
dotnet/runtime#29895
  • Loading branch information
jonclare committed Oct 22, 2020
1 parent 7cce8f8 commit 208f764
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using DomainLib.Aggregates;
using DomainLib.Persistence;
using DomainLib.Persistence.EventStore;
using DomainLib.Serialization;
using EventStore.ClientAPI;
using NUnit.Framework;
using Shopping.Domain.Aggregates;
using Shopping.Domain.Commands;
using Shopping.Domain.Events;
using Shopping.Infrastructure.JsonSerialization;

namespace Shopping.Infrastructure.Tests
{
Expand All @@ -32,18 +35,35 @@ public async Task PersistedRoundTripTest()

var eventsToPersist = result1.AppliedEvents.Concat(result2.AppliedEvents).ToList();

var serializer = new JsonEventSerializer();
serializer.RegisterEventTypeMappings(initialState.EventTypeMapping);
var serializer = CreateJsonSerializer(initialState.EventTypeMapping);
var repository = new EventStoreEventsRepository(EventStoreConnection, serializer);

var streamName = $"shoppingCart-{result2.NewState.Id.Value}";

var nextEventVersion = await repository.SaveEventsAsync(streamName, ExpectedVersion.NoStream, eventsToPersist);

var expectedNextEventVersion = eventsToPersist.Count - 1;

Assert.That(nextEventVersion, Is.EqualTo(expectedNextEventVersion));

var eventsFromPersistence = await repository.LoadEventsAsync<object>(streamName);
var eventsFromPersistence = (await repository.LoadEventsAsync<IDomainEvent>(streamName));
var loadedAggregate = ShoppingCart.FromEvents(eventsFromPersistence);

// Check the loaded aggregate root state.
Assert.That(loadedAggregate.Id, Is.EqualTo(shoppingCartId));
Assert.That(loadedAggregate.Items, Has.Count.EqualTo(2));
Assert.That(loadedAggregate.Items[0], Is.EqualTo("First Item"));
Assert.That(loadedAggregate.Items[1], Is.EqualTo("Second Item"));
}

private static IEventSerializer CreateJsonSerializer(IEventTypeMapping eventTypeMapping)
{
var serializer = new JsonEventSerializer();
serializer.RegisterConverter(new ShoppingCartCreatedConverter());
serializer.RegisterConverter(new ItemAddedToShoppingCartConverter());

serializer.RegisterEventTypeMappings(eventTypeMapping);

return serializer;
}

}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using System;
using System.Text.Json;
using System.Text.Json.Serialization;
using Shopping.Domain.Events;

namespace Shopping.Infrastructure.JsonSerialization
{
// HACK: Add a temporary manual converter. .NET Core 3.1 doesn't support constructors with parameters
public class ItemAddedToShoppingCartConverter : JsonConverter<ItemAddedToShoppingCart>
{
public override ItemAddedToShoppingCart Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
reader.Read(); // Id property name
reader.Read(); // Id property value
var id = reader.GetGuid();

reader.Read(); // Item property name
reader.Read(); // Item property value
var item = reader.GetString();

// Read the rest of the object. We don't need any of this
while (reader.Read())
{
}

return new ItemAddedToShoppingCart(id, item);
}

public override void Write(Utf8JsonWriter writer, ItemAddedToShoppingCart value, JsonSerializerOptions options)
{
writer.WriteStartObject();
writer.WriteString("Id",value.Id);
writer.WriteString("Item", value.Item);
writer.WriteEndObject();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System;
using System.Text.Json;
using System.Text.Json.Serialization;
using Shopping.Domain.Events;

namespace Shopping.Infrastructure.JsonSerialization
{
// HACK: Add a temporary manual converter. .NET Core 3.1 doesn't support constructors with parameters
public class ShoppingCartCreatedConverter : JsonConverter<ShoppingCartCreated>
{
public override ShoppingCartCreated Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
reader.Read(); // Id property name
reader.Read(); // Id property value
var id = reader.GetGuid();

// Read the rest of the object. We don't need any of this
while (reader.Read())
{
}

return new ShoppingCartCreated(id);
}

public override void Write(Utf8JsonWriter writer, ShoppingCartCreated value, JsonSerializerOptions options)
{
writer.WriteStartObject();
writer.WriteString("Id",value.Id);
writer.WriteEndObject();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,4 @@
<ProjectReference Include="..\Shopping.Domain\Shopping.Domain.csproj" />
</ItemGroup>

<ItemGroup>
<Folder Include="JsonSerialization\" />
</ItemGroup>

</Project>

0 comments on commit 208f764

Please sign in to comment.