2012-02-07 9 views
5

Dada almacén de eventos con los campos:Como recuperar acontecimientos históricos después de cambios en la estructura de dominio Evento

  • AggregateId: entero
  • Carga útil: blob
  • versión: número entero

que contiene eventos basado en:

public class OrderLineAdded 
{ 
    int Id; 
    short Quantity; 
} 

... y luego tiene más eventos añadidos con una estructura actualizada:

public class OrderLineAdded 
{ 
    int ProductId; // field name has changed 
    int Quantity; // field datatype has changed 
} 

Cuando se recupera estos datos histórica (para el análisis, etc.), ¿cómo reconstruir la carga útil binaria en datos significativos?

Nota: El código anterior no es un ejemplo de una buena implementación de tienda de eventos/eventos. Solo quiero saber cómo se debe manejar este escenario.

+0

molestaría que incrementar el número de versión para la segunda versión y deserialise basado en la versión? –

+0

@LukeMcGregor Sí, estaba pensando en esa línea. Quiero saber si hay un enfoque diferente/mejor? –

Respuesta

3

Rinat Abdullin describe algunas estrategias de control de versiones de eventos de dominio en su bliki de CQRS que puede ser útil leer.

https://abdullin.com/post/event-sourcing-versioning/

Se sugiere dos posibles enfoques:

  1. utilizar un serializador que puede hacer frente el cambio de nombre de las propiedades en su caso automáticamente como protobuf Serializador de Google.
  2. Implemente la siguiente interfaz para actualizar manualmente los eventos en memoria.
public interface IUpgradeDomainEvents 
{ 
    IEnumerable<IDomainEvent> Upgrade(IDomainEvent e, string id); 
} 
1

El único método que he visto para controlar la compatibilidad con versiones anteriores es la versión de cada cambio en su evento. Algunas personas crean nuevas versiones en un espacio de nombres diferentes, por lo que el espacio de nombre refleja la información de la versión/función:

namespace Foo.ProjectA.Release1 
{ 
    public interface ISomeEvent {...} 
} 

namespace Foo.ProjectA.Release3 
{ 
    public interface ISomeEvent {...} 
} 

otra parte, crear una nueva versión de la clase con la información de la versión/función en el nombre de la clase:

namespace Foo.ProjectA 
{ 
    public interface ISomeEvent {...} 
    public interface ISomeEvent_MoreRefinedVersion {...} 
} 

Personalmente, prefiero el enfoque anterior, a menos que la nueva versión agregue un significado semántico más específico al evento.

Cuestiones relacionadas