Как правильно использовать единицу работы / репозитории на бизнес-уровне?

Создав небольшое приложение с использованием шаблона «Единица работы / Репозиторий», я изо всех сил пытаюсь понять, как правильно использовать это на моем бизнес-уровне. В моем приложении есть уровень доступа к данным, который может быть либо 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.

Как правильно использовать единицу работы и репозитории на бизнес-уровне?

6
задан Cole Johnson 2 December 2013 в 18:23
поделиться