title: Should repositories be properties on the unit of work when using Entity Framework?
body: <p>I have scoured the web looking for a good implementation of the Repository/Unit of Work pattern using Entity Framework. Everything I've come across is either tightly coupled at some point in the abstraction or assumes that the <code>DbContext</code> used by the Unit of Work and Repositories is shared and should live for the entire <code>HTTP</code> request (instance per request via dependency injection).</p>
  
  <p>For example, assuming you are consuming repositories from the service layer, a service constructor might look like this:</p>
  
  <pre><code>public DirectoryService(IUnitOfWork unitOfWork, ICountryRepository countryRepo, IProvinceRepository provinceRepo)
  {
      /* set member variables... */
  }
  </code></pre>
  
  <p>The unit of work constructor might look like:</p>
  
  <pre><code>public UnitOfWork(IDbContext context)
  {
      _context = context;
  }
  </code></pre>
  
  <p>And a repository constructor might look like:</p>
  
  <pre><code>CountryRepository(IDbContext context)
  {
      _context = context;
  }
  </code></pre>
  
  <p>This solution makes the blind assumption that the Dependency injection is setting up the Unit of Work and Repositories to share the same IDbContext using instance per request. Is that really a safe assumption to make?</p>
  
  <p>If you are using dependency injection with instance per request, the same IDbContext will be injected into multiple units of work. The unit of work is no longer atomic, is it? I might have pending changes in one service that are then committed in another service because the context is shared across multiple units of work.</p>
  
  <p>To me it seems to make more sense to set up a <code>IDbContextFactory</code> and get a fresh database context with each unit of work.</p>
  
  <pre><code>public interface IDbContextFactory
  {
      IDbContext OpenContext();
  }
  
  public class UnitOfWork 
  {
      private IDbContextFactory _factory;
      private IDbContext _context;
  
      UnitOfWork(IDbContextFactory factory)
      {
          _factory = factory;
      }
  
      internal IDbContext Context
      {
          get { return _context ?? (_context = _factory.OpenContext()); }
      }
  }
  </code></pre>
  
  <p>The problem then becomes, how do I make my Unit of Work implementation available to the injected repositories? I don't want to assume instance per request because then I'm right back in the same boat I started in.</p>
  
  <p>The only thing I can think of is to follow Entity Framework's lead and make the repositories <code>(IDbSet&lt;T&gt;)</code> part of the unit of work <code>(DbContext)</code>.</p>
  
  <p>So then I might have units of work that look like this:</p>
  
  <pre><code>public class DirectoryUnitOfWork : IDirectoryUnitOfWork
  {
      private IDbContextFactory _factory;
      private IDbContext _context;
  
      public DirectoryUnitOfWork(IDbContextFactory factory)
      {
          _factory = factory;
      }
  
      protected IDbContext Context 
      {
          get { return _context ?? (_context = _factory.OpenContext()); }
      }
  
      public ICountryRepository CountryRepository
      {
          get { return _countryRepo ?? (_countryRepo = new CountryRepository(Context)); }
      }
  
      public IProvinceRepository ProvinceRepository
      {
          get { return _provinceRepo ?? (_provinceRepo = new ProvinceRepository(Context)); }
      }
  
      void Commit()
      {
          Context.SaveChanges();
      }
  }
  </code></pre>
  
  <p>Then my Directory service starts to look like this</p>
  
  <pre><code>public class DirectoryService : IDirectoryService
  {
      private IDirectoryUnitOfWork _unitOfWork;
  
      public DirectoryService(IDirectoryUnitOfWork unitOfWork)
      {
          _unitOfWork = unitOfWork;
      }
  
      public GetCountry(int id)
      {
          return _unitOfWork.CountryRepository.GetById(id);
      }
  
      public GetProvince(int id)
      {
          return _unitOfWork.ProvinceRepository.GetById(id);
      }
  
      public void AddProvince(Province province)
      {
          _unitOfWork.ProvinceRepository.Create(province);
          Country country = GetCountry(province.CountryId);
          country.NumberOfProvinces++; // Update aggregate count
          _unitOfWork.Commit();
      }
  
      /* ... and so on ... */
  }
  </code></pre>
  
  <p>It seems like a lot of work, but using this method leaves everything loosely coupled and unit testable. Am I missing an easier way, or is this a good way to do it <em><code>if</code></em> I am going to abstract away Entity Framework?</p>