2011-06-09 17 views
15

En este momento estamos construyendo una nueva arquitectura que se basa en los principios de CQRS y el diseño impulsado por dominio. Ahora estamos teniendo algunas discusiones sobre cómo debemos tratar con la comunicación externa. Para hacer la pregunta más concreta, utilizo el ejemplo de enviar una notificación SMS cuando un cliente crea un pedido.Enviando un correo electrónico o SMS usando CQRS y diseño impulsado por dominio

El cliente crea un NewOrderCommand que maneja el controlador de comando asociado. El controlador crea un nuevo objeto Order en el modelo de dominio, que genera un NewcustomerCreatedEvent. El objeto se guarda en el almacén de eventos y el evento se publica en todos los oyentes.

Hasta ahora todo bien, pero ahora la pregunta. ¿A dónde deberíamos enviar la notificación por SMS?

Nuestro primer instinto nos dijo que deberíamos enviarlo utilizando un oyente de eventos que escucha el NewCustomerCreatedEvent y envía el mensaje. El problema con este enfoque es que el envío del SMS también forma parte de nuestra lógica empresarial. Estamos vendiendo servicios alojados para que nuestros clientes puedan ver todos los mensajes SMS que se envían en su nombre. Debido a que el envío del mensaje tiene lugar fuera del dominio, no podemos hacer eso.

Así que creamos un dominio SMS y ahora cuando el detector de eventos recibe el evento NewCustomerCreatedEvent el controlador crea un nuevo comando SendSmsMessageCommand que creará un nuevo objeto SMSMessage en nuestro dominio, envía la notificación SMS y crea un evento SmsSent que usar para crear la vista.

Al principio estábamos enviando el mensaje SMS en el modelo de dominio, pero nos dimos cuenta de que esto podría dar algunos problemas. Digamos que después de enviar el SMS sucede algo (se lanza una excepción) y la transacción se retrotrae. Nuestro dominio admite esto completamente, por lo que estamos de acuerdo en que estamos bien, pero el mensaje SMS ya se envió, por lo que cuando se reenvía el comando, se enviará nuevamente la notificación por SMS.

Estábamos pensando en enviar los SMS en el evento SmSSent pero sería un poco extraño, porque el evento dice que el mensaje ya se envió pero no lo está.

El ejemplo anterior nos lleva a la pregunta de cómo lidiar con la comunicación externa en el concepto de diseño basado en dominio y CQRS? No solo estamos hablando de enviar una notificación SMS, sino también de enviar una factura al sistema de facturación externo y todo otro tipo de comunicación al mundo exterior. ¿Deberíamos hacer esto en el dominio porque es lógica de negocios o deberíamos hacerlo siempre en base a los eventos en nuestros controladores de eventos? Y si lo hacemos, ¿es aceptable usar eventos que digan que el mensaje se envía cuando aún no está listo?

Espero que ustedes ya se hayan ocupado de esta situación y puedan darnos algunos consejos sobre este tema.

+1

vergüenza que esta cuestión no atrajo más interés. ¿Has hecho más progresos/pensamientos sobre este tema? ¿Alguna vez repites eventos para reconstruir la tienda de lectura? En ese caso, ¿cómo se asegura de que los mensajes de texto no se envíen nuevamente? – Kimble

+1

relacionado: http://stackoverflow.com/questions/11015989/cqrs-when-to-send-confirmation-message?rq=1 // @Kimble –

Respuesta

2

Creo que un objeto de dominio para el mensaje SMS no es necesario. Solo necesita informar los SMS enviados al cliente, ¿correcto? Los mensajes SMS no se usan en ninguna lógica de dominio, ¿correcto?

Así que el operador enviará un SMS y luego publicará otro evento que dice que se envió un SMS y un controlador de eventos escuchará el mensaje SMS y materializará esa información en un modelo de lectura para que el cliente pueda verlos .

+0

Gracias por su respuesta. El SMS es solo un ejemplo. Como dije sobre comunicación externa en general. Cuando cambie el SMS a un HTTP POST a nuestro sistema de facturación, su recomendación sería la misma para enviarla en un controlador de eventos y permitir que ese evento maneje nuevos eventos. Solo para explicar por qué creamos y el dominio de SMS es porque somos nuestro propio intermediario de SMS. Hay una gran cantidad de lógica empresarial involucrada cuando enviamos un SMS como el operador para enviarlo. También deberíamos poder procesar informes de entrega para un mensaje SMS. – llMll

0

Puede usar una Saga o un Administrador de procesos como Microsoft lo llame. Esto básicamente escucha los eventos, que cambian el estado de la saga, y emite comandos basados ​​en la lógica de estado implementada en la saga.

En su caso, sería una saga de dos estados, que espera tanto CustomerCreatedEvent como OrderCreatedEvent, y, o bien emita un comando para enviar un sms, si tiene un contexto limitado especializado para la comunicación o llame a un servicio de infraestructura, a través de una interfaz, para enviar el sms.

Aquí puede encontrar el artículo de Microsoft en el patrón gerente saga/proceso:

https://msdn.microsoft.com/en-us/library/jj591569.aspx

Y dos artículos implementaciones que contienen:

http://danielwhittaker.me/2015/03/31/how-to-send-emails-the-right-way-in-a-cqrs-system/

http://blog.jonathanoliver.com/cqrs-sagas-with-event-sourcing-part-ii-of-ii/

Cuestiones relacionadas