Шаблон единицы работы в приложении asp.net mvc

Я просматривал этот замечательный блог под названием «NHibernate и шаблон единицы работы», и у вас есть вопрос о том, где лучше всего использовать UnitOfWork.Start в проекте asp.net mvc.

Мой SLN разбит на следующие проекты: -

 MVC project
 Repository
 NHibernateUnitOfWork

У меня есть интерфейс: -

 public interface INameRepository
 ...
       IList<Name> GetByOrigin(int OriginId)
 ...

У меня есть конкретная реализация

     public class NameRepository : INameRepository
     ...
          public  IList<Name> GetByOrigin(int OriginId) {
                using (UnitOfWork.Start()) {
                     var query = session.Linq<...
                     return query;
                }
          }
     ...

Мой вопрос: нужно ли обернуть все свои методы во все свои репозитории с помощью (UnitOfWork.Start ()) или есть лучший подход?

Я использую nHibernate, asp.net mvc.


person Fred Smith    schedule 30.12.2009    source источник


Ответы (2)


С шаблоном единицы работы вы не помещаете каждый метод доступа к данным в отдельную единицу работы. Вы используете единицу работы для всей работы, которую необходимо выполнить, что в большинстве случаев в веб-приложении является веб-запросом. Идея в том, что запрос может быть неудачным или успешным. Когда вы добавляете 2 элемента в базу данных во время одного запроса, должны быть добавлены оба элемента, или нет. Не только один из них. В большинстве случаев самый простой способ запустить единицу работы в mvc (или другом веб-приложении) - использовать методы запроса begin и end файла global.asax.

class Global
{
    BeginRequest()
    {
        servicelocater.get<unitofwork>().start();
    }

    EndRequest()
    {
        var unit = servicelocater.Get<Unitofwork>();
        try
        {
            unit.commit();
        }
        catch
        {
            unit.rollback();
            throw;
        }
    }
}

class Repository<T>
{
     public Repository(INHibernateUnitofwork unitofwork)
     {
         this.unitofwork = unitofwork;
     }

     public void Add(T entity)
     {
         unitofwork.session.save(entity);
     }
}
person Paco    schedule 30.12.2009
comment
Спасибо, это лучший подход. Просто нужно разобраться, есть ли активная транзакция и сбросить ее. Спасибо - person Fred Smith; 30.12.2009

Я думаю, что Sharp Architecture решает эту проблему достаточно хорошо. Что они делают, так это помещают единицу работы в фильтр действий ASP .Net MVC. В основном вы можете определить фильтр действий транзакции, например


public class TransactionAttribute : ActionFilterAttribute
{
      public override void OnActionExecuting(ActionExecutingContext filterContext)
      {
         UnitOfWork.Start();
      }

      public override void OnActionExecuted(ActionExecutedContext filterContext)
      {
         UnitOfWork.Stop();
      }
}

и в вашем классе контроллера поместите атрибут Transaction в свой метод результата действия

person Emmanuel    schedule 30.12.2009
comment
Недостатком этого подхода является то, что каждый субконтроллер / рендератор находится в отдельной единице работы. - person Paco; 30.12.2009