2011-09-16 20 views
8

Korzystanie z mechanizmu obsługi MongoDB w joliver/EventStore powodującego błąd Unknown discriminator value 'MyEvent'. Problem spowodowany jest tylko wtedy, gdy próbuję załadować wszystkie zdarzenia dla odtwarzając wydarzenia jak this.storeEvent.Advanced.GetFrom(new DateTime(2010, 1,1))Nieznana wartość dyskryminatora "MyEvent"

The problemów jest spowodowana w 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); 
    } 

Moja konfiguracja wygląda następująco:

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

Ale wypróbowałem prawie wszystkie rodzaje opcji serializera.

Odpowiedz

10

Spróbuj zarejestrować swoje obiekty (same wiadomości o zdarzeniach, a także tematy ładunków EventStore) za pomocą metody BsonClassMap.RegisterClassMap. Wygląda na to, że rozszerzenie mongo EventStore dobrze obsługuje ładunki ciągów, ale nie deserializowane obiekty ... przynajmniej rejestracja zaklasyfikowanego była rozwiązaniem w moim przypadku.

+2

Dziękuję. Kiedy zapisałem zatwierdzenia, sterownik mongo db zarejestrował same klasy, jednak w odpowiedzi (czysty odczyt) mapowanie nie zostało wykonane. – Jacee

+0

Dzięki, chociaż nie rozumiem, dlaczego to powinno być konieczne – JacobE

13

Ja też w to wpadłem. Zsolt's odpowiedź była dobrym punktem wyjścia, ale w końcu rozwiązałem ją nieco inaczej.

Zauważ, że nie tylko otrzymałem to, gdy myEventStore.Advanced.GetFrom(...); myEventStore.OpenStream(...) również nie działa. Ma to sens, ponieważ obie metody używają tego samego IPersistentStream i serializera.

Nie napotykam tego problemu, gdy po raz pierwszy utrwalam zdarzenie, przed pobraniem zdarzenia tego samego typu. Najwyraźniej MongoDB tworzy ClassMap, gdy jest proszony o serializację typu po raz pierwszy.

W każdym razie dla mnie rozwiązaniem było stworzenie mapy klas dla wszystkich typów zdarzeń podczas uruchamiania aplikacji. Zakładając, że wszystkie rodzaje są w zgromadzeniu SimpleCQRS.Event i czerpać z SimpleCQRS.Event, robię to tak:

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

Dla mnie to działa lepiej niż przy użyciu BsonClassMap.RegisterClassMap<TypeToMap> jak Zsolt sugeruje, ponieważ wymaga rodzajowego parametr typu, co oznacza, musisz manually add each event type.

+0

+1 pracował również dla mnie! – RobertMS

+0

Doskonały pomysł na przyszłość, z niewielkim drobnym drukiem/zastrzeżeniem, że a) wszystkie podklasy 'SimpleCQRS.Event' zostaną dodane w sposób niedyskryminujący, oraz że b) wszystkie podklasy" Known Type "muszą znajdować się w tym samym zespole. – StuartLC

Powiązane problemy