1

我正在尝试使用 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()我会得到一个异常,因为无法实例化抽象类。如果我将基类转换为接口,则事件对象为空,并且我存储在其中的对象会丢失。

有什么想法吗?

编辑 1

使用 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
    }

编辑 2

也不适用于这种方法;

    [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
        {

        }
    }
4

1 回答 1

1

您能否使用最新版本(v3.05+)的 ServiceStack Redis 客户端再试一次:

https://github.com/ServiceStack/ServiceStack.Redis/downloads

客户端使用的 ServiceStack Json Serializer 刚刚添加了对抽象/接口类型的反序列化支持,这些类型将在客户端的最新版本中。

注意:这是通过将__type信息嵌入到 JSON 有效负载中来工作的,该有效负载告诉序列化器应该反序列化到哪个具体类。它只为抽象/接口/对象类型嵌入此信息。因此,当您序列化时,您需要转换为抽象类型,例如:

redis.Store((DomainEvent)userPromoEvent);

或者如果添加到列表中:

redis.As<DomainEvent>().Lists["urn:domainevents"].Add(userPromoEvent);

这些示例现在按照新添加的DomainEvents 单元测试的指示工作:)

[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(); 
}
于 2011-11-15T18:32:45.280 回答