Eshoponcontainers: [Bug] Deserialization of IntegrationEvent

Created on 5 Jul 2018  路  5Comments  路  Source: dotnet-architecture/eShopOnContainers

Possible Issue

Deserialization of IntegrationEvent based classes won't assign the same Id and CreationDate properties of the published events.

Example

From my understanding based on the current implementation of the IntegrationEvent those properties being { get; } only will not be populated by the current deserialization provided by the event bus implementations (AzureServiceBus and RabbitMQ) but instead get new values based on the constructor (issue link on Newtonsoft.Json project).

IntegrationEvent snippet

public class IntegrationEvent
{
    public IntegrationEvent()
    {
        Id = Guid.NewGuid();
        CreationDate = DateTime.UtcNow;
    }

    public Guid Id  { get; }
    public DateTime CreationDate { get; }
}

deserialization snippet

var integrationEvent = JsonConvert.DeserializeObject(message, eventType);

Question

Is this an unintended behavior (bug) or an integration event is _by design_ supposed to have a new Id and CreationDate whenever it gets within the context of a microservice (subscriber)?.

--
Best regards,
Diogo Pinho

backlog-item bug

Most helpful comment

Hi @Diggzinc, this is actually a bug.

We intent to fix it this way to minimize changes and still keep the class immutable (in practice) and also "extend" this "immutability" implementation to the derived events:

public class IntegrationEvent
{
  public IntegrationEvent()
  {
    Id = Guid.NewGuid();
    CreationDate = DateTime.UtcNow;
  }

  [JsonProperty]
  public Guid Id { get; private set; }
  [JsonProperty]
  public DateTime CreationDate { get; private set; }
}

This solves the issue from the deserializer perspective, as it can find its way through the private setter, but has to be tested in the real app to be sure it works as expected.

Hope this helps in the meantime.

All 5 comments

I noticed this as well when trying to implement EventHandlers and essentially loosing the Event.Id and Event.CreationDate that makes it possible to trace where and when the events originated. I think everything has been designed from a Publishing perspective rather than a Subscribing.

I've ended up bringing in an IIntegrationEvent interface, you can then either take the default IntegrationEvent which overwrites the Id and CreationDate or implement your own Event to be used in the handler and give it a constructor where the Id and CreationDate can be deserialsed from the json message body. Somewhere in the ProcessEvent method (my code's diverged a bit from back porting to .net 4.6)

It is a fairly lengthy refactoring to find all the IntegrationEvents but it lets you implement your own event handlers where you can preserve the Id and CreationDate.

@RossHNPC thanks for the input.

Since I was using the eShopOnContainers as a reference for my daily work i didn't have to go through the refactoring part 馃槂.

I did end up with a similar solution that you presented though. Extracting an IIntegrationEvent interface and providing event implementations that provide correct deserialization.

Hi @Diggzinc, thanks for the heads up and thanks to @RossHNPC too, for a nice solution.

We'll check on this issue.

Hi @Diggzinc, this is actually a bug.

We intent to fix it this way to minimize changes and still keep the class immutable (in practice) and also "extend" this "immutability" implementation to the derived events:

public class IntegrationEvent
{
  public IntegrationEvent()
  {
    Id = Guid.NewGuid();
    CreationDate = DateTime.UtcNow;
  }

  [JsonProperty]
  public Guid Id { get; private set; }
  [JsonProperty]
  public DateTime CreationDate { get; private set; }
}

This solves the issue from the deserializer perspective, as it can find its way through the private setter, but has to be tested in the real app to be sure it works as expected.

Hope this helps in the meantime.

Closing this issue as it was solved with commit 06de1b68e3a758c854084200924c7e0799aa8b53

Was this page helpful?
0 / 5 - 0 ratings