title: How to handle unit of work with dependency injection and repositories
body: <p>
  I've inherited some code that has a UnitOfWorkFactory which creates a unit of work inside each repository method. The problem is that a single repository method is rarely the full unit of work so if something goes wrong in say <code>OrderService.PlaceOrder</code>, it can't just rollback/discard that unit of work as it's not one unit.</p>
  
  <p>Looking at the code I think the unit of work should be moved into either the service class or the presenter. The problem I then have is then how do I pass it to either the service or the repository? The presenter gets passed an instance of the service and the service gets passed an instance of the repository. </p>
  
  <p>I could create the unit of work and have it injected the constructors of the services, repositories and  presenters but then it would live beyond a single unit of work. This is a desktop app so the presenter and any services it gets passed can be alive for multiple units of work.</p>
  
  <p>The only way I can think that I could pass the unit of work on is to add it as a parameter to all service/repository methods. I can't help thinking there must a better way than that though, am I missing something?</p>
  
  <p>The code looks something like this:</p>
  
  <p>Repository:</p>
  
  <pre class="lang-cs prettyprint-override"><code>class OrderRepository
  {
      public UnitOfWorkFactory UnitOfWorkFactory;
  
      public OrderRepository(UnitOfWorkFactory unitOfWorkFactory)
      {
          UnitOfWorkFactory = unitOfWorkFactory;
      }
  
      public void Save(Order order)
      {
          using(var uow = UnitOfWorkFactory.Create())
          {
              // save order
              uow.commit();
          }
      }
  }
  </code></pre>
  
  <p>Serivce:</p>
  
  <pre class="lang-cs prettyprint-override"><code>class OrderService
  {
      protected IOrderRepository OrderRepository;
      protected IProductService ProductService;
  
      public OrderService(IOrderRepository orderRepository, IProductRepository productService)
      {
          OrderRepository = orderRepository;
          ProductService = productService;
      }
  
      public void PlaceOrder(Order order)
      {
          foreach(var item in order.Items)
          {
              if(!ProductService.IsInstock(item.Product, item.Quantity))
                  throw new ProductOutOfStockException(product);
  
              ProductService.MarkForDispatch(item.Product, item.Quantity);
          }
  
          OrderRepository.Save(order);
      }
  
      public void CancelOrder(Order order)
      {
          ProductService.UnmarkForDispatch(item.Product, item.Quantity);
  
          order.IsCanceled = true;
          OrderRepository.Save(order);
      }
  }
  </code></pre>
  
  <p>Presenter:</p>
  
  <pre class="lang-cs prettyprint-override"><code>class OrderPresenter
  {
      protected IOrderView OrderView;
      protected IOrderService OrderService;
  
      public OrderPresenter(IOrderView orderView, IOrderService orderService)
      {
          OrderView = orderView;
          OrderService = orderService;
      }
  
      public void PlaceOrder()
      {
          OrderService.PlaceOrder(order);
      }
  
      public void CanelOrder()
      {
          OrderService.CancelOrder(order);
      }
  }
  </code></pre>