patterns framework example driven domain ddd actions validation domain-driven-design cqrs

validation - framework - Validación de la singularidad al utilizar CQRS y la fuente de eventos



infrastructure layer c# (3)

Estoy tratando de implementar mi propia infraestructura CQRS con Event Sourcing para aprender mejor. Como proyecto de ejemplo, estoy implementando un motor de blog, sé que puede que no sea un ajuste perfecto, pero solo quiero trabajar en algo real.

El problema al que he llegado ahora es la validación. Cada publicación tiene un shortUrl , y el shortUrl debe ser único, pero ¿dónde debería colocar esta validación en el dominio? Sé que tendré esa validación incluso antes de enviar el comando al leer en mi tienda de lectura para verificar si es válida al crear un comando crear mensaje o actualizar comando.

Puedo pensar en dos "soluciones".

  1. Tenga un agregado de Blog que mantenga un seguimiento de todas las configuraciones relacionadas con el blog y también referencias a todas las publicaciones. Pero el problema con esto en mi opinión es que tengo que manejar la comunicación entre agregados en ese escenario, así como cada vez que necesito validar la singularidad de un shortUrl . Necesito leer todos los eventos del almacén de eventos para crear todas las publicaciones. y eso parece complicado.
  2. La segunda alternativa que tengo es cuando el evento se activa y mi controlador de eventos que crea el modelo de lectura activa un evento de URL corto duplicado cuando se da cuenta de que tendrá dos URL cortas que apuntan a diferentes publicaciones. ¿Es válido tener el modelo de lectura para disparar eventos cuando detecta errores?

¿Hay más alternativas? Tenga en cuenta que sé que mi dominio puede no ser el mejor ajuste para cqrs y DDD, pero estoy haciendo esto para aprender en un dominio pequeño.


Depende de lo que ''el negocio'' quiera que suceda. Si desea que el cliente (creador de los comandos) sea responsable de elegir una URL corta, debe tener un almacén de lectura que verifique la singularidad de la misma. Cuando el usuario escribe una URL corta, la vista debe verificar que la URL corta sea única y presente un error de validación si no lo es. Cada vez que se guarda una publicación, un evento publicará la información actualizada (incluida la URL corta) que mantiene el almacén de lectura sincronizado.


He leído las diferentes respuestas sobre esta y la pregunta relacionada.

La decisión se reduce a la corrección. Si puede perdonar y aceptar un comportamiento imperfecto para cierto grado de operación, su problema es mucho más sencillo de resolver, especialmente con garantías de consistencia débil.

Sin embargo, si desea coherencia, debe utilizar un servicio de persistencia que tenga fuertes garantías de consistencia.

Por ejemplo, el comando que crea la URL corta validará que el almacén de lectura ya no contiene una URL tan corta y solo confirmaremos nuestro evento, si primero podemos confirmar los cambios en nuestro almacén de lectura.

Si podemos confirmar nuestros cambios en nuestra tienda de lectura, no hemos violado ninguna restricción de unicidad (suponiendo que su tienda de lectura aplique dicha restricción) y luego podemos continuar.

Sin embargo, dado que tenemos dos transacciones que no necesariamente están en la misma base de datos, podemos fallar después de la primera confirmación. Esto está bien porque la operación en su conjunto también fallará. El almacén de lectura reflejará un estado incoherente durante algún tiempo, pero tan pronto como reparemos el agregado, el almacén de lectura volverá a estar en un estado consistente.

Como procedimiento de mantenimiento, podríamos reparar periódicamente agregados que hayan estado sujetos a posibles errores. Y puede hacer esto introduciendo un indicador de error que solo se borra si ambas transacciones se confirman correctamente.

Hubo un ejemplo en el que un banco le permitiría a un usuario sobregirar su cuenta porque tienen recargos por eso para compensar. Esto plantea preguntas porque parecería descuidado resolver un problema como ese, incluso flojo. Algunos lo llaman inteligente. No se que pensar. El banco probablemente tiene suficiente dinero para cubrirlo, por lo que es mejor que lo ignoren, pero no es así como funciona el mundo actualmente. De todos modos, estoy divagando.

Desde una postura de corrección, nuestra tienda de lectura tiene una fuerte garantía de consistencia y escribiríamos nuestra proyección de tal manera que no podamos comprometer una transacción en la tienda de lectura si el saldo se pone en negativo. Como tal, lo peor que puede pasar es que se deduzca un cargo de la tienda de lectura, pero la operación nunca se confirmó completamente en la tienda de eventos. El usuario vería que falta dinero en su cuenta hasta que el procedimiento de mantenimiento detectó el indicador de error y curó la cuenta. Esto creo que es un compromiso de trabajo.


Iría por un servicio de dominio que solo sea responsable de generar ShortURL únicos. Puede utilizar una base de datos transaccional para implementar este comportamiento. Normalmente, este servicio lo usaría el comando que maneja parte del agregado de BlogPost. Si hay un ShortURL duplicado, puede disparar un DuplicateUrlErrorEvent. Puede realizar una captura previa en la interfaz de usuario (pero nunca al 100%) creando un modelo de consulta delgado con la misma fuente de datos, por lo que puede consultar si una URL abreviada es única antes de enviar la publicación (como lo describe la respuesta de @RanR ).