Реализация вашего IUnitOfWork может использовать любые технологические средства «транзакционализации» изменений между различными агрегатами за один раз, которые вы пожелаете, будь то TransactionScope, SqlTransaction или любое другое средство, которое вы выберете. Однако это не отменяет необходимости использования IUnitOfWork.
Репозитории предназначены для конкретного агрегата. Если вы одновременно сохраняете изменения только одного агрегатного типа, вы можете использовать только репозиторий. Но если вы одновременно сохраняете разные агрегаты и вам нужно, чтобы это постоянство было «транзакционизировано», чтобы изменения сохранялись все или ничего, то именно здесь в игру вступает шаблон «Единица работы».
В вашем примере мы скажем, что вы используете Linq в качестве своего OR/M, и вы сохраняете свои агрегаты в хранилище данных SQL, но хотите обернуть сохраняемость в TransactionScope. У вас может быть такое определение IUnitOfWork:
public interface IUnitOfWork
{
void MarkDirty(IAggregateRoot entity);
void MarkNew(IAggregateRoot entity);
void MarkDeleted(IAggregateRoot entity);
void Commit();
void Rollback();
}
Тогда ваша реализация может быть такой:
public LinqTransactionScopeUnitOfWork : IUnitOfWork
{
public void Commit()
{
using (TransactionScope scope = new TransactionScope())
{
foreach (IAggregateRoot root in Changes)
{
//Save root based on how it was marked and what it's concrete type is using Linq.
}
scope.Complete();
}
}
}
Основная идея здесь заключается в том, что TransactionScope — это один из способов реализации IUnitOfWork, но наличие контракта Unit of Work позволяет вам предоставлять различные реализации в зависимости от вашей среды.
Надеюсь это поможет!
person
Aaron Hawkins
schedule
07.01.2013