Tengo una aplicación ASP.NET MVC, que utiliza un servicio de consulta para obtener datos y un servicio de comando para enviar comandos. Mi pregunta es sobre la parte del comando.
Si llega una solicitud, el servicio de comando usa un despachador de comando que enrutará el comando a su controlador de comando designado. Este controlador de comandos valida primero el comando y, si todo es aceptable, ejecuta el comando.
Ejemplo concreto: AddCommentToArticleCommandHandler recibe un AddCommentToArticleCommand, que tiene un ArticleId, CommentText y EmailAddress.
Primero; la validación tiene que ocurrir, como: - verifique si el artículo existe - verifique si el artículo no está cerrado - verifique si el texto del comentario está completado y entre 20 y 500 caracteres - verifica si la dirección de correo electrónico está completa y tiene un formato válido.
Me pregunto dónde poner esta validación.
1 / en el controlador de comandos en sí. Pero entonces, no se puede reutilizar en otros controladores de comandos.
2 / en la entidad de dominio. Pero como una entidad de dominio no conoce los repositorios o servicios, no puede hacer la validación necesaria (no puede verificar si existe un artículo). Pero, por otro lado, si la entidad no contiene lógica, se convierte en un simple contenedor de datos, que no sigue los principios DDD.
3 / el controlador de comandos utiliza validadores, de modo que la validación se puede reutilizar en otros controladores de comandos.
4 / Otros mecanismos?
Estoy buscando la cadena de responsabilidades para este ejemplo en particular y qué objetos (entidades, repositorios, ...) juegan un papel en él.
¿Tiene ideas sobre cómo implementar esto, comenzando desde el controlador de comandos hasta los repositorios?
fuente
Respuestas:
Creo que necesita separar dos tipos de validación en este caso; validación de dominio y validación de aplicaciones .
La validación de la aplicación es lo que tiene cuando verifica que la propiedad del comando 'texto' tiene entre 20 y 200 caracteres; entonces usted valida esto con la GUI y con un ver-modelo-validador que también se ejecuta en el servidor después de una POST. Lo mismo ocurre con el correo electrónico (por cierto, espero que se dé cuenta de que un correo electrónico como `32.d +" Hello World .42 "@ mindomän.local" es válido según la RFC).
Entonces tienes otra validación; compruebe que el artículo existe: debe hacerse la pregunta de por qué el artículo no debería existir si efectivamente hay un comando enviado desde la GUI que trata de adjuntarle un comentario. ¿Su GUI finalmente fue consistente y usted tiene una raíz agregada, el artículo, que puede eliminarse físicamente del almacén de datos? En ese caso, simplemente mueve el comando a la cola de errores porque el controlador de comandos no puede cargar la raíz agregada.
En el caso anterior, tendría una infraestructura que maneja los mensajes de envenenamiento; por ejemplo, volverían a intentar el mensaje de 1 a 5 veces y luego lo moverían a una cola de poision donde podría inspeccionar manualmente la colección de mensajes y volver a enviar los relevantes. Es bueno monitorear.
Entonces ahora hemos discutido:
Validación de la aplicación
Faltan raíces agregadas + colas de veneno
¿Qué pasa con los comandos que no están sincronizados con el dominio? Tal vez tenga una regla en su lógica de dominio que dice que después de 5 comentarios a un artículo, solo se permiten comentarios por debajo de 400 caracteres, pero un tipo llegó demasiado tarde con el quinto comentario y llegó a ser el sexto: la GUI no lo captó porque no era coherente con el dominio en el momento en que él envió su comando; en este caso, tiene una 'falla de validación' como parte de la lógica de su dominio y devolvería el evento de falla correspondiente.
El evento podría tener la forma de un mensaje en un intermediario de mensajes o en su despachador personalizado. El servidor web, si la aplicación es monolítica, podría escuchar sincrónicamente tanto el evento de éxito como el evento de falla mencionado y mostrar la vista / parcial apropiada.
A menudo tiene eventos personalizados que significan fallas para muchos tipos de comandos, y es este evento al que se suscribe desde la perspectiva del servidor web.
En el sistema en el que estamos trabajando, estamos haciendo una solicitud-respuesta con comandos / eventos a través de un bus + broker de mensajes Mass Transit + RabbitMQ y tenemos un evento en este dominio en particular (modelando un flujo de trabajo en parte) que se denomina
InvalidStateTransitionError
. La mayoría de los comandos que intentan moverse a lo largo de un borde en el gráfico de estado pueden hacer que este evento suceda. En nuestro caso, estamos modelando la GUI según un paradigma eventualmente consistente, por lo que enviamos al usuario a una página de "comando aceptado" y, a partir de entonces, dejamos que las vistas del servidor web se actualicen pasivamente a través de suscripciones de eventos. Cabe mencionar que también estamos haciendo eventos de origen en las raíces agregadas (y también lo haremos para las sagas).Como puede ver, muchas de las validaciones de las que está hablando son en realidad validaciones de tipo de aplicación, no lógica de dominio real. No hay problema en tener un modelo de dominio simple si su dominio es simple pero está haciendo DDD. Sin embargo, a medida que continúe modelando su dominio, descubrirá que es posible que el dominio no sea tan simple como resultó. En muchos casos, la entidad / raíz agregada podría aceptar una invocación de método causada por un comando y cambiar parte de su estado sin siquiera realizar ninguna validación, especialmente si confía en sus comandos como lo haría si los valida en el servidor web que usted controla
Puedo recomendar ver las dos presentaciones sobre DDD de Norwegian Developer Conference 2011 y también la presentación de Greg en Öredev 2010 .
Saludos, Henke
fuente
EDITAR: enlace WaybackMachine: http://devlicio.us/blogs/billy_mccafferty/archive/2009/02/17/a-response-to-validation-in-a-ddd-world.aspx
No hay una respuesta fácil.
fuente