Комбинирование Unit of Work
и Repository Pattern
- это то, что используется довольно широко в наши дни. Поскольку Martin Fowler говорит, цель использования UoW
заключается в создании Бизнес-транзакции, хотя она не знает, как хранилища фактически работа (постоянная неосведомленность). Я рассмотрел множество реализаций; и игнорируя конкретные детали (конкретный/абстрактный класс, интерфейс,...), они более или менее похожи на следующие:
public class RepositoryBase<T>
{
private UoW _uow;
public RepositoryBase(UoW uow) // injecting UoW instance via constructor
{
_uow = uow;
}
public void Add(T entity)
{
// Add logic here
}
// +other CRUD methods
}
public class UoW
{
// Holding one repository per domain entity
public RepositoryBase<Order> OrderRep { get; set; }
public RepositoryBase<Customer> CustomerRep { get; set; }
// +other repositories
public void Commit()
{
// Psedudo code:
For all the contained repositories do:
store repository changes.
}
}
Теперь моя проблема:
UoW
предоставляет открытый метод Commit
для сохранения изменений. Кроме того, поскольку каждый репозиторий имеет общий экземпляр UoW
, каждый Repository
может получить доступ к методу Commit
в UoW. Вызов его одним репозиторием делает все остальные хранилища также сохраняют свои изменения; следовательно, вся концепция транзакции обрушивается:
class Repository<T> : RepositoryBase<T>
{
private UoW _uow;
public void SomeMethod()
{
// some processing or data manipulations here
_uow.Commit(); // makes other repositories also save their changes
}
}
Я думаю, что это должно быть запрещено. Учитывая цель UoW
(бизнес-транзакция), метод Commit
должен быть открыт только тем, кто запустил Бизнес-транзакция, например Business Layer. Меня удивило то, что я не мог найти статей, посвященных этой проблеме. Во всех из них Commit
может быть вызвано любым репо, которое вводится.
PS: Я знаю, что я могу сказать моим разработчикам не называть Commit
в Repository
, но надежная архитектура более надежна, чем надежные разработчики!