В контексте DDD, где должна начинаться и заканчиваться транзакция, когда вы имеете дело с событиями домена?
Инфраструктура. Слой имеет реализацию UoW
/// => configured via DI as Per Request
class UnitOfWork : IUnitOfWork
{
ITransaction _transaction;
static ISessionFactory _factory;
ISession _session
UnitOfWork()
{
_session = _factory.OpenSession();
_transaction = _session.BeginTransaction(); ///=> start transaction
}
void Commit()
{
try
_transaction.Commit();
catch
_transaction.Rollback();
finally
Dispose();
}
}
Application.Layer UseCase Handler
class SomeAppServiceUseCaseHandler : IUseCaseHandler
{
IUnitOfWork _uow;
ISomeRepo _repo;
AppService(IUnitOfWork uow, ISomeRepo repo)
{
_uow = uow;
_repo = repo;
}
void UseCaseHandler(Request request)
{
SomeAggregate agg = _repo.GetAggregate(request.Id)
agg.DoSomethingToChangeState();
_repo.UpdateAgg(agg);
_uow.Commit(agg); ///=> commit changes for this transaction success
}
}
и в Domain.Layer, имеющем метод, который также добавит Domain.Event в список событий домена для агрегата.
SomeAggregate : AggregateRoot
{
DoSomethingToChangeState()
{
.... do something
var someObject;
base.AddEvent(new SomethingHappenedEvent(someObject)));
}
}
Application.Layer имеет обработчики Domain.Event
class SomethingHappenedEventHander : Handler<SomethingHappenedEvent>
{
IRepo repo;
IUnitOfWork _uow;
DomainEventHander(IRepo repo, IUnitOfWork uow)
{
_repo = repo;
_uow= uow;
}
HandleEvent(someObject)
{
AnotherAggregate agg = new AnotherAggregate ();
agg.DoSomeCommand(someObject);
_repo.Create(agg);
_uow.Commit(); ///=> commit changes for same transaction fail, should rollback prev transaction as well
}
}
Я чувствую, что это не так
Кто должен публиковать событие? из того, что я вижу, UoW должен делать это в методе Commit (), но я не думаю, что это правильно, я упал, что UoW не должен этого делать, но я не вижу, кто еще мог.
Если в какой-то момент в цепи что-то не получается, я уже зафиксировал некоторые данные, которые, скорее всего, я бы не хотел делать, если что-то по пути не получится.
Так как же правильно обращаться с этими двумя ситуациями?