我正在尝试使用C#和[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; }
}
如果我执行roots.GetAll()
我得到一个异常,因为抽象类无法实例化。如果我将基类转换为接口,则Events对象为null,并且我存储在那里的对象会丢失。
有什么想法吗?
使用v3.03和此代码无欢乐:
[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
}
也没有使用这种方法;
[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
{
}
}
答案 0 :(得分:1)
您可以再次使用ServiceStack Redis客户端的最新版本(v3.05 +):
https://github.com/ServiceStack/ServiceStack.Redis/downloads
客户端使用的ServiceStack Json Serializer刚刚添加了对抽象/接口类型的反序列化的支持,这些类型将在最新版本的客户端中。
注意:这可以通过将 __ type 信息嵌入到JSON有效负载中来实现,该有效负载告诉序列化程序应该反序列化的具体类。它仅为Abstract / interface / object类型嵌入此信息。因此,在序列化时,您需要转换为抽象类型,例如:
redis.Store((DomainEvent)userPromoEvent);
或添加到列表中:
redis.As<DomainEvent>().Lists["urn:domainevents"].Add(userPromoEvent);
现在,这些示例的工作方式与新添加的DomainEvents Unit Tests:)
相同[Test]
public void Can_Retrieve_DomainEvents()
{
var userId = Guid.NewGuid();
var client = new RedisClient("localhost");
client.FlushAll();
client.As<DomainEvent>().Lists["urn:domainevents-" + userId].Add(
new UserPromotedEvent { UserId = userId });
var users = client.As<DomainEvent>().Lists["urn:domainevents-" + userId];
Assert.That(users.Count, Is.EqualTo(1));
var userPromoEvent = (UserPromotedEvent)users[0];
Assert.That(userPromoEvent.UserId, Is.EqualTo(userId));
}
[Test]
public void Can_from_Retrieve_DomainEvents_list()
{
var client = new RedisClient("localhost");
var users = client.As<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();
}