Eu sugeriria encapsular o comportamento de adiamento em um decorador :
public class TransactionDeferral : IMessageProducer
{
public TransactionDeferral(IMessageProducer decoratedMessageProducer, ITransaction deferringTransaction)
{
_decoratedMessageProducer = decoratedMessageProducer;
_deferringTransaction = deferringTransaction;
}
public void Publish<TMessage>(TMessage message)
{
if (_deferringTransaction.IsCommitted)
_decoratedMessageProducer.Publish(message);
else
_deferredMessages.Add(message);
}
private void DeferringTransaction_Committed(obsect sender, TransactionCommitedEventArgs e)
{
foreach (var message in _deferredMessages)
{
_decoratedMessageProducer.Publish(message);
}
}
}
O consumidor dessa interface pode ser então injetado um IMessagePublisher
que é na realidade uma instância de TransactionDeferral
decorando o verdadeiro publicador de mensagens, tornando-se assim completamente agnóstico da transação.
Se o consumidor tiver que estar ciente da conclusão das operações de publicação de mensagens individuais, provavelmente você poderá modificar sua interface original para o método Publish
para retornar um Task
que pode ser eventualmente await
ed:
public interface IMessageProducer
{
Task Publish<TMessage>(TMessage message);
}