Единица работы и шаблон репозитория
-
20-09-2019 - |
Вопрос
У меня есть настройка шаблона репозитория с использованием NHibernate.Базовый класс выглядит так:
public interface IUnitOfWork : IDisposable
{
void Commit();
void Rollback();
}
// generic NHibernate implementation of IUnitOfWork here
public class NHibernateRepositoryBase<T> : IRepository<T>
{
private NHibernateUnitOfWork _unitOfWork;
public NHibernateRepositoryBase(NHibernateUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
public T Get(object id)
{
return _unitOfWork.Session.Get<T>(id);
}
// ...
}
Как видите, я разрешаю заполнять единицу работы через конструктор (с использованием StructureMap).Я заполняю объекты репозитория в своих веб-службах ASP.NET следующим образом:
[WebService(Namespace = "...")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class ModuleService : System.Web.Services.WebService
{
public IUserAccountRepository UserAccountRepo { get; set; }
public ModuleService()
{
// tell IoC to inject properties
ObjectFactory.BuildUp(this);
}
// ...
}
Как вы, возможно, догадались, моя проблема в том, что в результате проектирования я потерял контроль над жизненным циклом единицы работы.Ранее я сделал единицу работы контекстно-зависимым объектом, и репозиторий получал ссылку на нее примерно так:
public class NHibernateRepositoryBase<T> : IRepository<T>
{
public T Get(object id)
{
return NHibernateUnitOfWork.GetCurrent().Session.Get<T>(id);
}
// ...
}
Этот предыдущий дизайн позволял мне контролировать жизненный цикл единицы работы в моем коде, создавая единицу работы из UnitOfWorkFactory в операторе using.Я пытался передать большую часть работы контейнеру IoC, но мне кажется, что я на самом деле сделал шаг назад.Что вы думаете по поводу той или иной реализации?
Решение
Обычно полезно позволить вашему IoC-контейнеру обрабатывать как можно больше.В Интернете шаблон единицы работы обычно инициализируется в начале запроса и фиксируется в конце (откатывается, если есть какие-либо исключения).Таким образом, ваш репозиторий будет использовать ISession в конструкторе вместо unitofwork.Таким образом, вашему репозиторию не придется иметь дело с фиксацией или чем-то еще, и это будет обрабатываться автоматически за вас.