Persistencia y eventos de dominio con persistencia de objetos ignorantes

He estado estudiando el diseño impulsado por dominio junto coneventos de dominio. Realmente me gustan las separaciones de preocupaciones que proporcionan esos eventos. Me encontré con un problema con el orden de persistir un objeto de dominio y generar eventos de dominio. Me gustaría generar eventos en los objetos de dominio, pero quiero que sean ignorantes de persistencia.

He creado un básicoShoppingCartService, con esteCheckout método:

public void Checkout(IEnumerable<ShoppingCartItem> cart, Customer customer)
{
    var order = new Order(cart, customer);

    _orderRepositorty.Add(order);
    _unitOfWork.Commit();
}

En este ejemplo, el constructor deOrder&nbsp;levantaría unOrderCreated&nbsp;evento que puede ser manejado por ciertos controladores. Sin embargo, no quiero que esos eventos se generen cuando la entidad aún no persiste o cuando persiste de alguna manera falla.

Para resolver este problema, he descubierto varias soluciones:

1. Elevar eventos en el servicio:

En lugar de generar el evento en el objeto de dominio, podría generar eventos en el servicio. En este caso, elCheckout&nbsp;método elevaría elOrderCreated&nbsp;evento. Una de las desventajas de este enfoque es que al mirar elOrder&nbsp;objeto de dominio, no está claro qué eventos se generan mediante qué métodos. Además, un desarrollador debe acordarse de generar el evento cuando se crea un pedido en otro lugar. No se siente bien.

2. Cola de eventos de dominio

Otra opción es poner en cola eventos de dominio y aumentarlos cuando persiste con éxito. Esto podría lograrse mediante unusing&nbsp;declaración por ejemplo:

using (DomainEvents.QueueEvents<OrderCreated>())
{
    var order = new Order(cart, customer);

    _orderRepositorty.Add(order);
    _unitOfWork.Commit();
}

losQueueEvents<T>&nbsp;método establecería un valor booleano paratrue&nbsp;y elDomainEvents.Raise<T>&nbsp;El método pondría en cola el evento en lugar de ejecutarlo directamente. En la disposición de devolución de llamada deQueueEvent<T>, los eventos en cola se ejecutan, lo que garantiza que la persistencia ya haya sucedido. Esto parece bastante complicado y requería que el servicio supiera qué evento se está generando en el objeto de dominio. En el ejemplo que proporcioné, también solo admite un tipo de evento que se generará, sin embargo, esto podría solucionarse.

3. Persistir en el evento de dominio

Podría persistir el objeto usando un evento de dominio. Esto parece estar bien, excepto por el hecho de que el controlador de eventos que persiste en el objeto debería ejecutarse primero, sin embargo, leí en alguna parte que los eventos de dominio no deberían depender de un orden específico de ejecución. Quizás eso no sea tan importante y los eventos de dominio puedan saber de alguna manera en qué orden deben ejecutarse los controladores. Por ejemplo: supongamos que tengo una interfaz que define un evento de dominiomanipulador, una implementación se vería así:

public class NotifyCustomer : IDomainEventHandler<OrderCreated>
{
   public void Handle(OrderCreated args)
   {
       // ...
   }
}

Cuando quiero manejar la persistencia en el uso de un controlador de eventos también, crearía otro controlador, derivado de la misma interfaz:

public class PersistOrder : IDomainEventHandler<OrderCreated>
    {
       public void Handle(OrderCreated args)
       {
           // ...
       }
    }
}

AhoraNotifyCustomer&nbsp;el comportamiento depende del orden que se guarda en la base de datos, por lo que elPersistOrder&nbsp;El controlador de eventos debe ejecutarse primero. ¿Es aceptable que estos manejadores introduzcan una propiedad, por ejemplo, que indique el orden de su ejecución? Un complemento de la implementación de laDomainEvents.Raise<OrderCreated>()&nbsp;método:

foreach (var handler in Container.ResolveAll<IDomainEventHandler<OrderCreated>>().OrderBy(h => h.Order))
{
    handler.Handle(args);
}

Ahora mi pregunta es, ¿tengo otras opciones? ¿Me estoy perdiendo de algo? ¿Y qué opinas de las soluciones que propuse?