未知的鉴别器值'MyEvent'

时间:2011-09-16 23:43:59

标签: mongodb-.net-driver event-sourcing event-store

joliver/EventStore中使用MongoDB持久性引擎导致错误Unknown discriminator value 'MyEvent'。问题仅在我尝试加载所有事件以重播this.storeEvent.Advanced.GetFrom(new DateTime(2010, 1,1))

等事件时引起

问题是由ExtensionsMethods.cs

引起的
public class MyClassEvent : IDomainEvent { ... }

public static Commit ToCommit(this BsonDocument doc, IDocumentSerializer serializer)
    {
        if (doc == null)
            return null;

        var id = doc["_id"].AsBsonDocument;
        var streamId = id["StreamId"].AsGuid;
        var commitSequence = id["CommitSequence"].AsInt32;

        var events = doc["Events"].AsBsonArray.Select(e => e.AsBsonDocument["Payload"].IsBsonDocument ? BsonSerializer.Deserialize<EventMessage>(e.AsBsonDocument["Payload"].AsBsonDocument) : serializer.Deserialize<EventMessage>(e.AsBsonDocument["Payload"].AsByteArray)).ToList();
        var streamRevision = doc["Events"].AsBsonArray.Last().AsBsonDocument["StreamRevision"].AsInt32;
        return new Commit(
            streamId,
            streamRevision,
            doc["CommitId"].AsGuid,
            commitSequence,
            doc["CommitStamp"].AsDateTime,
            BsonSerializer.Deserialize<Dictionary<string, object>>(doc["Headers"].AsBsonDocument),
            events);
    }

我的配置是这样的:

 Wireup.Init()                
            .UsingMongoPersistence(connectionName, new DocumentObjectSerializer())
            .UsingBsonSerialization()    
            .UsingAsynchronousDispatcher()                                
            .PublishTo(this.container.Resolve<IPublishMessages>())
            .Build();

但是已经尝试了几乎所有类型的序列化器选项。

2 个答案:

答案 0 :(得分:13)

我也碰到了这个。 Zsolt's回答是一个很好的起点,但我最终解决的问题略有不同。

请注意,我不仅在myEventStore.Advanced.GetFrom(...)时获得此信息。 myEventStore.OpenStream(...)也失败了。这是有道理的,因为两种方法都使用相同的IPersistentStream和序列化器。

在检索相同类型的事件之前,当我第一次持久化事件时,我不会遇到此问题。显然,MongoDB会在第一次要求它序列化类型时创建ClassMap

无论如何,对我来说,解决方案是在应用程序启动时为我的所有事件类型创建一个类映射。假设所有类型都在SimpleCQRS.Event的程序集中,并从SimpleCQRS.Event派生,我这样做:

var types = Assembly.GetAssembly(typeof(SimpleCQRS.Event))
                    .GetTypes()
                    .Where(type => type.IsSubclassOf(typeof(SimpleCQRS.Event)));
foreach (var t in types)
    BsonClassMap.LookupClassMap(t);

对我而言,这比使用像Zsolt建议的BsonClassMap.RegisterClassMap<TypeToMap>更好,因为这需要一个泛型类型参数,这意味着您必须manually add each event type

答案 1 :(得分:10)

尝试使用BsonClassMap.RegisterClassMap方法注册对象(本身就是事件消息以及EventStore有效负载的主题)。似乎EventStore的mongo扩展很好地处理了字符串有效负载,但没有处理反序列化的对象......至少注册分类是我的解决方案。