I’m trying to create a simple event store using C# and [ServiceStack] Redis.
public class AggregateEvents
{
public Guid Id { get; set;}
public List<DomainEvent> Events { get; set; }
}
public abstract class DomainEvent { }
public class UserRegisteredEvent : DomainEvent
{
public Guid UserId { get; set; }
public string Name { get; set; }
}
public class UserPromotedEvent : DomainEvent
{
public Guid UserId { get; set; }
public string NewRole { get; set; }
}
if I do a roots.GetAll() I get an exception because the abstract class could not be instantiated. If I turn the base class into an interface instead, the Events object is null and the objects I stored in there get lost.
Any thoughts?
Edit 1
No joy using v3.03 and this code:
[Test]
public void foo()
{
var client = new RedisClient("localhost");
var users = client.GetTypedClient<AggregateEvents>();
var userId = Guid.NewGuid();
var eventsForUser = new AggregateEvents
{
Id = userId,
Events = new List<DomainEvent>()
};
eventsForUser.Events.Add(new UserPromotedEvent { UserId = userId });
users.Store(eventsForUser);
var all = users.GetAll(); // exception
}
Edit 2
Also not worked with this approach;
[Test]
public void foo()
{
var userId = Guid.NewGuid();
var client = new RedisClient("localhost");
client.As<DomainEvent>().Lists["urn:domainevents-" + userId].Add(new UserPromotedEvent {UserId= userId});
var users = client.As<DomainEvent>().Lists["urn:domainevents-" + userId];
foreach (var domainEvent in users) // exception
{
}
}
Can you try again with the latest version (v3.05+) of the ServiceStack Redis client:
https://github.com/ServiceStack/ServiceStack.Redis/downloads
The ServiceStack Json Serializer which the client uses has just added support for deserialization of Abstract/interface types which will be in the latest version of the client.
Note: this works by embedding __type information into the JSON payload which tells the serializer what concrete class it should deserialize into. It only embeds this information for Abstract/interface/object types. So you when you serialize you will need to cast to the abstract type, e.g:
or if adding to a list:
These examples now work as indicated by the newly added DomainEvents Unit Tests 🙂