¿Dónde generar eventos de dominio dependientes de la persistencia: servicio, repositorio o interfaz de usuario?

Mi aplicación ASP.NET MVC3 / NHibernate tiene el requisito de activar y manejar una variedad de eventos relacionados con mis objetos de dominio. Por ejemplo, unaOrder objeto podría tener eventos comoOrderStatusChanged oNoteCreatedForOrder. En la mayoría de los casos, estos eventos provocan el envío de un correo electrónico, por lo que no puedo dejarlos en la aplicación MVC.

He leído a través de Udi DahanDomain Events y docenas de otras ideas sobre cómo hacer este tipo de cosas, y decidí usar un host basado en NServiceBus que maneje mensajes de eventos. He realizado algunas pruebas de prueba de concepto y esto parece funcionar bien.

Mi pregunta eswhat capa de aplicación debería generar los eventos. No quiero activar los eventos hasta que el objeto en cuestión haya sido persistido con éxito (no puedo enviar un correo electrónico indicando que se creó una nota si la persistencia falla).

Otra preocupación es que, en algunos casos, un evento está vinculado a un objeto que está debajo de una raíz agregada. En el ejemplo anterior, unaNote se guarda agregándolo a laOrder.Notes colección y guardar el pedido. Esto plantea un problema, ya que dificulta evaluar qué eventos deberían activarse cuando unOrder está guardado. Me gustaría evitar tener que extraer una copia actual del objeto y buscar diferencias antes de guardar la copia actualizada.

¿Es apropiado que la UI genere estos eventos? Sabe qué eventos han ocurrido y puede dispararlos solo después de que la capa de servicio guarde con éxito el objeto. Algo parece incorrecto acerca de tener un controlador disparando eventos de dominio.

Debería el repositorio disparar eventos después de persistir con éxito?

ebo separar los eventos por completo, hacer que el repositorio almacene unEvent objeto que luego es recogido por un servicio de sondeo ylueg ¿convertido en un evento para NServiceBus (o manejado directamente desde el servicio de sondeo)?

¿Hay una mejor manera de hacer esto? ¿Quizás hacer que mis objetos de dominio pongan en cola eventos que son activados por la capa de servicio solo después de que el objeto persiste?

Actualizar Tengo una capa de servicio, pero parece engorroso y excesivo tener que pasar por un proceso de comparación para determinar qué eventos deben activarse cuando se guarda una raíz agregada determinada. Debido a que algunos de estos eventos son granulares (p. Ej., "El estado del pedido cambió"), creo que tendría que recuperar una copia de base de datos del objeto, comparar las propiedades para crear eventos, guardar el nuevo objeto y luego enviar los eventos a NServiceBus cuando la operación de guardar se completó correctamente.

Actualiza

Lo que terminé haciendo, después de la respuesta que publiqué a continuación way debajo de), fue construir en mis entidades de dominio unaEventQueue propiedad que era unaList<IDomainEvent>. Luego agregué eventos a medida que los cambios en el dominio lo merecían, lo que me permitió mantener la lógica dentro del dominio, lo que creo que es apropiado ya que estoy disparando eventos basados en lo que está sucediendo dentro de una entidad.

Luego, cuando persisto el objeto en mi capa de servicio, proceso esa cola y realmente envío los eventos al bus de servicio. Inicialmente, estaba planeando usar una base de datos heredada que usara PK de identidad, por lo que tuve que procesar posteriormente estos eventos para completar el ID de la entidad, pero finalmente decidí cambiar a unaGuid.Comb PK que me permite omitir ese paso.

Respuestas a la pregunta(6)

Su respuesta a la pregunta