Создав небольшое приложение с использованием шаблона «Единица работы / Репозиторий», я изо всех сил пытаюсь понять, как правильно использовать это на моем бизнес-уровне. В моем приложении есть уровень доступа к данным, который может быть либо NHibernate, либо Entity Framework. Я могу легко переключаться между ними.
У меня есть несколько репозиториев, например, Customer, Order и т. Д. Моей единицей работы будет ISession или Object Context, в зависимости от того, с каким DAL я хочу тестировать.
Мой бизнес-уровень содержит один бизнес-метод - CreateOrder (). Я изо всех сил пытаюсь понять, где на бизнес-уровне я должен инициализировать свою единицу работы и свои репозитории.
Сосредоточившись на Nhibernate, мой DAL выглядит так:
public class NHibernateDAL : IUnitOfWork
{
log4net.ILog log = log4net.LogManager.GetLogger(typeof(NHibernateDAL));
ISession context;
public NHibernateDAL()
{
context = SessionProvider.OpenSession();
this.Context.BeginTransaction();
CurrentSessionContext.Bind(context);
}
public ISession Context
{
get { return context; }
}
public void Commit()
{
this.Context.Transaction.Commit();
context.Close();
}
public void Dispose()
{
ISession session = CurrentSessionContext.Unbind(SessionProvider.SessionFactory);
session.Close();
}
}
На моем бизнес-уровне я хочу знать, где я должен объявлять свою единицу работы и репозитории. Объявлены ли они на уровне класса или в методе CreateOrder?
Например:
public class BusinessLogic
{
UnitOfWork _unitOfWork = new UnitOfWork(NHibernateDAL);
NhRepository<Order> _orderRepository = new NhRepository<Order>(_unitOfWork);
NhRepository<Customer> _customerRepository = new NhRepository<Customer>(_unitOfWork);
....
public void CreateOrder(.....)
{
Order order = new Order();
_orderRepository.Add(order);
_unitOfWork.Commit();
}
}
Приведенный выше код работает только при первом вызове метода CreateOrder (), но не для последующих вызовов, потому что сеанс закрыт. Я попытался удалить вызов context.Close () после фиксации транзакции, но это тоже не удалось. Хотя описанный выше подход не работает, мне кажется более правильным объявить мои репозитории и единицу работы с этой областью действия.
Однако, если я реализую его, как показано ниже, вместо этого он будет работать нормально, но кажется неестественным объявить репозитории и единицы работы в рамках самого метода. Если бы у меня была тонна бизнес-методов, я бы объявлял репозитории и Единицы работы повсюду:
public class BusinessLogic
{
public void CreateOrder(.....)
{
UnitOfWork _unitOfWork = new UnitOfWork(NHibernateDAL);
var _orderRepository = new NhRepository<Order>(_unitOfWork);
NhRepository<Customer> _customerRepository = null;
Order order = new Order();
_orderRepository.Add(order);
_unitOfWork.Commit();
}
}
Если бы я реализовал это с помощью объявления уровня класса, я думаю, мне понадобились бы какие-то средства для повторного открытия того же единица работы в начале метода CreateOrder.
Как правильно использовать единицу работы и репозитории на бизнес-уровне?