Совместное использование единицы работы многими службами в ASP.NET MVC 3 - PullRequest
4 голосов
/ 04 октября 2011

мои контроллеры используют 2 или более сервисов. В свою очередь, мои службы создают и используют свой собственный экземпляр класса Unit of Work (с доступом к репозиториям).

Я бы хотел, чтобы мои сервисы использовали один и тот же экземпляр Unit of Work и делали его тестируемым. Мои вопросы:

  1. Должен ли я вводить единицу работы и услуги своим контроллерам?
  2. Мне бы тоже нужно было ввести Единицу работы в мои услуги. куда я должен сделать это? Большое вам спасибо.

Ответы [ 3 ]

7 голосов
/ 05 октября 2011

Мне нравится комбинировать DI с фильтром действий, таким образом, контейнер может управлять областью работы, но метод begin / commit / rollback вызывается для вас автоматически, и вам не придется возиться с этим на каждом действие.

Это немного сложнее, потому что обычно фильтры действий НЕ повторно создаются для каждого запроса, поэтому, когда у вас есть зависимость, которой вы действительно хотите быть для запроса (единица работы), вам нужно поработать над магией.

Вот как я это делаю, используя Ninject и Ninject.Web.Mvc

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
    public class UnitOfWorkAction : Attribute
    {
    }

    public class UnitOfWorkActionFilter : IActionFilter
    {
        private IUnitOfWork _unitOfWork;

        public UnitOfWorkActionFilter(IUnitOfWork unitOfWork)
        {
            _unitOfWork = unitOfWork;
        }

        public void OnActionExecuting(ActionExecutingContext filterContext)
        {
            _unitOfWork.Begin();
        }

        public void OnActionExecuted(ActionExecutedContext filterContext)
        {
            if (filterContext.Exception == null)
                {
                    try
                    {
                        _unitOfWork.Commit();
                    }
                    catch
                    {
                        _unitOfWork.Rollback();
                        throw;
                    }
                }
                else
                {
                    _unitOfWork.Rollback();
                }
        }
    }

Затем я настраиваю, как атрибут должен использоваться в App_Start / NinjectMVC3.cs

kernel.BindFilter<UnitOfWorkActionFilter>(FilterScope.Action, 0)
                .WhenActionMethodHas<UnitOfWorkAction>();
//also make sure your IUnitOfWork is bound per request, obviously

И, наконец, пример Действие

[UnitOfWorkAction]
public ActionResult SomeAction(int id)
{
     //invoke your services here, and the uow will be automatically committed or rolled back when the action returns
 }

Также стоит отметить, что этот подход позволяет вам вносить конструктор зависимостей в ваш фильтр действий, а не просто вводить свойства, что я очень предпочитаю.

5 голосов
/ 05 октября 2011

1) Я не думаю, что внедрение единицы работы в контроллере пользовательского интерфейса - это хорошая идея, попробуйте отделить логику и транзакцию от пользовательского интерфейса.

2) Да, вы можете внедрить UoW в свой сервис, предпочтительно в качестве конструктора, внедренного через контейнер IoC. некоторые проектируют его как статическую фабрику, но я предпочитаю использовать его как параметр, введенный в конструктор

public class MyService : IMyService
{
  IUnitOfWork _unitOfWork;

  public MyService(IUnitOfWork uow)
  {
    _unitOfWork = uow;
  }

  public void DoSomeOperation(SampleParam param)
  {
    _unitOfWork.BeginTrx();
    //  do some work 
    _unitOfWork.Commit();
  }
}

или с использованием статической фабрики

public class MyService : IMyService
{
  public void DoSomeOperation(SampleParam param)
  {
    using(UnitOfWork.Start())
    {
      //  do some work 
    }
  }
}
2 голосов
/ 05 октября 2011

Мне нравится ответ Мухаммеда Абеда, я еще не набрал достаточно очков, чтобы добавить комментарий к его сообщению, поэтому я просто попытаюсь упомянуть, что в этих случаях вам нужно убедиться, что Единица работы помечена как единая экземпляр или он не будет разделен между службами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...