Search code examples
c#jsondeserializationeventstoredb

How to parse back data from EventStore stream to correct type?


I stored the event data in EventStore:

var data = new EventData(Guid.NewGuid(),
                         @event.GetType().ToString(),
                         true,
                         @event.ToJsonBytes(), 
                         @event.GetType().ToJsonBytes());

this.connection.AppendToStreamAsync(this.stream + "/" + aggregateId, 
                                    ExpectedVersion.Any, data);

Seems to work. But how to parse back the data from EventStore without giving the concrete type?

I tried this way, but this only parses the data for the base class:

foreach (var data in result.Events)
{
   var @event = data.Event.Data.ParseJson<Event>();
   if (@event != null) // event contains only the base type data
   {
      events.Add(@event);
   }
}

How to get back the data for SomeSpecialEvent that is derived from Event? There are several Event types and I can't put all in here (storage mechanism should be unaware of the concrete type).

Any ideas how to put the T into the .ParseJson without using generics?


Solution

  • Found a solution by myself:

            var result = this.connection.ReadStreamEventsForwardAsync(this.stream + "/" + aggregateId, 0, 4095, false).Result;
    
            foreach (var data in result.Events)
            {
                var assemblyQualifiedName = data.Event.Metadata.ParseJson<string>();
                var type = Type.GetType(assemblyQualifiedName);
                var json = Helper.UTF8NoBom.GetString(data.Event.Data);
                var @event = JsonConvert.DeserializeObject(json, type) as Event;
                if (@event != null)
                {
                    events.Add(@event);
                }
            }
    

    You need to add the type into metadata when saving:

               var type = @event.GetType().AssemblyQualifiedName;
    
                var data = new EventData(
                    Guid.NewGuid(),
                    @event.GetType().Name,
                    true,
                    @event.ToJsonBytes(),
                    type.ToJsonBytes());