2011-09-16 8 views
8

joliver/EventStoreのMongoDB永続エンジンを使用すると、エラーUnknown discriminator value 'MyEvent'が発生します。私は問題がExtensionsMethods.cs未知の識別子値 'MyEvent'

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); 
    } 

私の構成で発生しthis.storeEvent.Advanced.GetFrom(new DateTime(2010, 1,1))

のようなイベントを再生するために、すべてのイベントをロードしようとすると、問題がのみ発生し、このようなものです:

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

しかし、ほぼすべての種類のシリアライザオプションを試しました。

答えて

10

BsonClassMap.RegisterClassMapメソッドを使用して、オブジェクト(イベントメッセージとイベントストアのペイロードのサブジェクト)を登録しようとします。 EventStoreのmongo拡張は文字列のペイロードをうまく処理するが、逆シリアル化されたオブジェクトは処理しないようだ...少なくともクラス分けされたものを登録することは私の場合の解決策であった。

+2

ありがとうございます。私がコミットを保存すると、mongo dbドライバはクラス自体を登録しましたが、返信(純粋な読み込み)ではマッピングが行われませんでした。 – Jacee

+0

ありがとう、なぜこれが必要なのかわからないが – JacobE

13

私もこの問題に対処しました。 Zsolt's回答は良い出発点でしたが、私はそれを少しずつ解決しました。

私がこれを取得したのは、myEventStore.Advanced.GetFrom(...)です。 myEventStore.OpenStream(...)も失敗します。両方のメソッドが同じIPersistentStreamとシリアライザを使用するため、これは意味があります。

同じタイプのイベントを取得する前に、イベントを最初に保持したときにこの問題に遭遇することはありません。明らかにMongoDBは初めてタイプをシリアライズするように要求されたときにClassMapを作成します。

とにかく、私のソリューションは、アプリケーションの起動時にすべてのイベントタイプのクラスマップを作成することでした。私にとって

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

ことは意味し、ジェネリック型パラメータを必要とするため、これは、ジョルトようBsonClassMap.RegisterClassMap<TypeToMap>を示唆している使用してより良い作品:SimpleCQRS.Eventの組み立てにあり、SimpleCQRS.Eventから派生するすべてのタイプを想定すると、私はこのようにそれを行いますあなたはmanually add each event typeする必要があります。

+0

+1も私のために働いた! – RobertMS

+0

a)すべての「SimpleCQRS.Event」サブクラスが無差別に追加され、b)すべての「Known Type」サブクラスが同じアセンブリ内に存在しなければならないという細かい細かい点に注意してください。 – StuartLC

関連する問題