2011-09-16 17 views
8

Usando el motor de persistencia MongoDB en joliver/EventStore causando el error Unknown discriminator value 'MyEvent'. El problema sólo se produce cuando intento cargar todos los eventos para reproducir los eventos como this.storeEvent.Advanced.GetFrom(new DateTime(2010, 1,1))Valor discriminador desconocido 'MyEvent'

los temas es causado en 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); 
    } 

Mi configuración es la siguiente:

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

Pero he probado casi todo tipo de opciones de serializador.

Respuesta

10

Intente registrar sus objetos (los mensajes de evento así como también los temas de las cargas útiles de EventStore) usando el método BsonClassMap.RegisterClassMap. Parece que la extensión mongo de EventStore maneja bien las cargas útiles de la cadena, pero no los objetos deserializados ... al menos registrar la clase fue la solución en mi caso.

+2

Gracias. Cuando guardé las confirmaciones, el controlador mongo db registró las clases en sí, sin embargo, en respuesta (lectura pura) la asignación no se realizó. – Jacee

+0

Gracias, aunque no puedo ver por qué esto debería ser necesario – JacobE

13

Acabo de toparme con esto también. Zsolt's respuesta fue un buen punto de partida, pero terminé resolviéndolo un poco diferente.

Tenga en cuenta que no solo recibí esto cuando myEventStore.Advanced.GetFrom(...); myEventStore.OpenStream(...) también falla. Esto tiene sentido, porque ambos métodos usan el mismo IPersistentStream y el serializador.

No me encuentro con este problema cuando la primera persistencia de un evento, antes de recuperar un evento del mismo tipo. Aparentemente MongoDB crea un ClassMap cuando se le pide que serialice un tipo por primera vez.

De todos modos, para mí, la solución fue crear un mapa de clases para todos mis tipos de eventos al inicio de la aplicación. Suponiendo que todo tipo se encuentran en el montaje de SimpleCQRS.Event y derivar de SimpleCQRS.Event, lo hago de esta manera:

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

Para mí esto funciona mejor que usar BsonClassMap.RegisterClassMap<TypeToMap> como Zsolt sugiere, porque eso requiere un parámetro de tipo genérico, es decir, tienes que manually add each event type.

+0

¡+1 también funcionó para mí! – RobertMS

+0

Excelente idea de futuro, con solo algunas pequeñas letras pequeñas/advertencias que a) todas las subclases 'SimpleCQRS.Event' se agregarán indiscriminadamente, y que b) todas las subclases' Known Type' deben residir en el mismo ensamblaje. – StuartLC

Cuestiones relacionadas