Pregunta

Si se asume un problema de dominio de desbordamiento de pila y la siguiente definición de eventos:

UserRegistered(UserId, Name, Email)
UserNameChanged(UserId, Name)
QuestionAsked(UserId, QuestionId, Title, Question)

Suponiendo que el siguiente estado de sucesos de almacenamiento (en el orden de aparición):

1) UserRegistered(1, "John", "john@gmail.com")
2) UserNameChanged(1, "SuperJohn")
3) UserNameChanged(1, "John007")
4) QuestionAsked(1, 1, "Help!", "Please!")

Suponiendo que el siguiente modelo de lectura desnormalizado para las preguntas del anuncio (para la primera página del SO):

QuestionItem(UserId, QuestionId, QuestionTitle, Question, UserName)

Y el siguiente controlador de eventos (que se basa desnormalizará modelo de lectura):

public class QuestionEventsHandler
{
    public void Handle(QuestionAsked question)
    {
        var item = new QuestionItem(
            question.UserId, 
            question.QuestionId, 
            question.Title, 
            question.Question, 
            ??? /* how should i get name of the user? */);
        ...
    }
}

Mi pregunta es ¿Cómo puedo encontrar el nombre del usuario que se hizo una pregunta? O más comunes: ¿Cómo debo manejar eventos si mi modelo de lectura desnormalizado requiere datos adicionales que no se existe en el evento en particular

?

He examinado muestras de CQRS incluyendo SimpleSQRS de Greg Young y Fohjin muestra de Marcos Nijhof. Pero me parece que se operan únicamente con los datos que se incluyen en eventos.

¿Fue útil?

Solución

Sólo enriquecer el evento con toda la información necesaria.

El enfoque de Greg, por lo que recuerdo, -. Enriquecer el evento al crear y almacenar / publicarlo esta manera

Otros consejos

En lo personal creo que no hay nada de malo en buscar el nombre del usuario desde dentro del controlador de eventos. Pero si usted está en una posición donde no se puede consultar el nombre del modelo de lectura del usuario entonces me presento un controlador de eventos adicional para QuestionEventsHandler, para controlar el evento UserRegistered.

De esta forma el QuestionEventsHandler podría mantener su propio repositorio de nombres de usuario (usted no necesitaría para almacenar el correo electrónico de los usuarios). El manejador QuestionAsked continuación, puede consultar el nombre del usuario directamente desde su propio repositorio (como Rinat Abdullin dijo almacenamiento es barato!).

Además, ya su QuestionItem leer modelo sostiene el nombre del usuario, lo que se necesita para controlar el evento UserNameChanged dentro del QuestionEventsHandler, así como asegurar el campo de nombre dentro del QuestionItem es de hasta al día.

Para mí esto parece menos esfuerzo que 'el enriquecimiento de los eventos' y tiene la ventaja de no dependencias inspirándose en otras partes del sistema y sus modelos de lectura.

eventos tirar de la EventStore.

Recuerde - Sus modelos de lectura necesita tener acceso de sólo lectura a la EventStore ya. Modelos leídos son desechables. Ellos simplemente se almacenan en caché vistas. Usted debe ser capaz de eliminar / expirar sus modelos de lectura en cualquier momento - y automáticamente reconstruir sus ReadModels del EventStore. Por lo tanto -. ReadModelBuilders sus ya deben ser capaces de consulta para los eventos pasados ??

public class QuestionEventsHandler
{
    public void Handle(QuestionAsked question)
    {
        // Get Name of User
        var nameChangedEvent = eventRepository.GetLastEventByAggregateId<UserNameChanged>(question.UserId);

        var item = new QuestionItem(
            question.UserId, 
            question.QuestionId, 
            question.Title, 
            question.Question, 

            nameChangedEvent.Name
    }
}

También se dan cuenta - la necesidad repositorio EventStore no sea el verdadero EventStore, aunque ciertamente podría ser. La ventaja de los sistemas distribuidos es que se puede replicar fácilmente la EventStore, si lo necesitas, más cerca de sus ReadModels.

Me encontré con este exactamente el mismo escenario ... donde necesitaba más datos que estaba disponible en un solo evento. Esto es especialmente cierto para los eventos de tipo Cree que requieren que pueblan un nuevo ReadModel con el estado inicial.

A partir de los modelos de lectura: Se podría tirar de otros modelos de lectura. Pero realmente no recomiendo esto, como era de introducir una gran bola de barro dependencia donde las vistas dependen de vistas dependerá de puntos de vista.

Los datos adicional en Eventos: Usted realmente no quiere inflar sus eventos con todos los datos adicionales que necesita para las vistas. Es realmente le duele cuando sus cambios de dominio y que tienen que migrar eventos. Eventos de dominio tienen fines específicos - que representan los cambios de estado. No ver los datos.

Espero que esto ayude -

Ryan

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top