2011-01-14 14 views
18

En nuestra aplicación levantamos eventos de dominio cuando algo cambia en el modelo de dominio. Algunas de las tareas que realizan los controladores de eventos deben realizarse dentro de la misma transacción que se utilizó cuando se produce el evento, otras tareas deben realizarse fuera de esta transacción.¿Se deberían generar eventos de dominio dentro o fuera de una transacción?

Por ejemplo,

Cuando se añade una de pedido de a una entidad Orden, se provoca el evento dominio OrderLineAdded, un evento de dominio cambia el estado del modelo de dominio (por lo que debe ser realizado en la misma transacción), entonces cuando se completa la transacción, la IU debe actualizarse.

¿Cómo abordaría este problema?

  1. Levante dos eventos, uno dentro de la transacción y otro fuera de la transacción.
  2. Levante el evento dentro de la transacción, pero use el controlador de eventos para enviar una solicitud de Async para actualizar la UI?

La opción 1 parece confusa, ya que los nombres de eventos deben indicar que están dentro o fuera de una transacción, pero con la opción 2 los manejadores del evento de dominio siempre deben asumir que se llaman sincrónicamente desde una transacción.

¿Tal vez hay un mejor enfoque?

Respuesta

16

Tuve un problema similar. El modelo de dominio fue publicar eventos (usando la técnica Udi Dahan describe here). Luego me di cuenta de que mis controladores relacionados con la interfaz de usuario se invocan incluso si algo sale mal y la transacción se retrotrae más tarde.

Para arreglar esto, introduje otro rol en el sistema, otro tipo de manejador de eventos. Tengo ITransactionalEventHadneler y INonTransactionalEventHandler. Los primeros fueron invocados sincrónicamente de inmediato en el método DomainEvents.Publish(). Estos últimos se pusieron en cola para ser invocados tan pronto como se haya confirmado la transacción (utilizando los ganchos System.Transactions). La solución funcionó bien y fue bastante legible y mantenible.

+0

Esto suena como una buena solución, ¿cómo se denominan los eventos para distinguir los eventos transaccionales de los no transaccionales? – Andronicus

+0

Me basé solo en la interfaz implementada. No tenía ninguna convención de nomenclatura. –

+1

@Szymon: Ha pasado un tiempo, pero por "ganchos", te refieres a [TransactionCompleted] (http: // msdn.microsoft.com/en-us/library/system.transactions.transaction.transactioncompleted.aspx) evento en la clase .NET 'Transaction'? ¿Tienes un ejemplo? – dstj

1

Creo que ambas enfoque podría ser bueno, sólo se adhieren a la misma aproximación en cada parte de su código:

  1. que necesitará dos (o más) controladores de eventos, uno para el contexto del dominio modelo que está dentro del alcance de la transacción y otro (s) para los contextos auxiliares, como la interfaz de usuario. El código de su dominio no debería importar qué otras partes del código hacen, solo notifíqueles sobre el cambio en los datos del dominio.
  2. su método de controlador de eventos de código de dominio puede enviar eventos asincrónicos a la UI u otros módulos. Los eventos de dominio deben ser sincrónicos, de lo contrario necesitaría compromisos de dos fases para mantener la transaccionalidad.

personalmente me gusta opción 2 más, ya que mantiene el limpiador de código de dominio y mediante el uso de la comunicación asíncrona se desacoplan del núcleo y otros módulos, por lo tanto problemas en los módulos externos no impedirá el funcionamiento del núcleo. Por otro lado, puede haber circunstancias donde la opción 1 es más ventajosa.

Cuestiones relacionadas