title: EF6, Unit of Work and Repository Pattern - Is this the wrong pattern for a sync service?
body: <p>I'm writing a sync service between our Salesforce environment and our local environment.  My use of the Salesforce API is purely on a batch level due to limitations on # of API requests per day, although I do have details on failures at the atomic level.  However, I would like to save changes on a atomic level in my local environment as I don't want an entire transaction to fail if one entity fails.</p>
  
  <p>I am using Entity Framework 6 with a Unit of Work and Repository pattern.  Here is my relevant code (Implementation Details Below):</p>
  
  <p>IUnitOfWork</p>
  
  <pre><code>public interface IUnitOfWork: IDisposable
  {
      IReadUpdateRepository&lt;EntityType1&gt; EntityType1Repository { get; }
      ISyncRepository&lt;EntityType2&gt; EntityType2Repository { get; }
      ISyncRepository&lt;EntityType3&gt; EntityType3Repository { get; }
  ...other repos
      void SaveChanges();
  }
  </code></pre>
  
  <p>Implementation of IUnitOfWork</p>
  
  <pre><code>public class UnitOfWork : IUnitOfWork
  {
      private bool _isDisposed;
      private DbContext _context;
      private ISyncRepository&lt;Entity&gt; _entityRepo;
  
  ...other private repos
      public UnitOfWork(DbContext context)
      {
          _context = context;
      }
  
  
      public ISyncRepository&lt;Entity&gt; EntityRepository
      {
          get
          {
              if (_entityRepo == null)
                  _entityRepo = new GenericSyncRepository&lt;Entity&gt;(_context);
  
              return _entityRepo ;
          }
      }
  
  ...other getters for other repos
  
      public void SaveChanges()
      {
          //client classes handle all errors here
          _context.SaveChanges();
      }
  
      private void dispose(bool isDisposing)
      {
          if (!_isDisposed)
          {
              if (isDisposing)
                  _context.Dispose();
          }
  
          _isDisposed = true;
      }
  
      public void Dispose()
      {
          dispose(true);
      }
  }
  </code></pre>
  
  <p>ISyncRepository</p>
  
  <pre><code>public interface ISyncRepository&lt;T&gt; where T : BaseEntity
  {
      void DeleteItems(IEnumerable&lt;T&gt; items);
      void DeleteItemsById(IEnumerable&lt;int&gt; ids);
      void DeleteItem(T item);
      void InsertItems(IEnumerable&lt;T&gt; items);
      void Insert(T item);
      T GetItemById(int id);
      List&lt;T&gt; GetItems(Expression&lt;Func&lt;T, bool&gt;&gt; predicate = null,     Func&lt;IQueryable&lt;T&gt;, IOrderedQueryable&lt;T&gt;&gt; orderBy = null, string includeProperties = "");
  
  }
  </code></pre>
  
  <p>Implementation of ISyncRepository</p>
  
  <pre><code>public class GenericSyncRepository&lt;T&gt; : ISyncRepository&lt;T&gt; where T : BaseEntity
  {
      private readonly DbContext _context;
      private readonly DbSet&lt;T&gt; _set;
  
      public GenericSyncRepository(DbContext context)
      {
          _context = context;
          _set = _context.Set&lt;T&gt;();
      }
  
      public T GetItemById(int id)
      {
          var result = _set.Find(id);
  
          return result;
      }
  
      public List&lt;T&gt; GetItems(Expression&lt;Func&lt;T, bool&gt;&gt; predicate = null, Func&lt;IQueryable&lt;T&gt;,IOrderedQueryable&lt;T&gt;&gt;  orderBy = null ,string includeProperties = "")
      {
          IQueryable&lt;T&gt; query = _set.AsExpandable();
  
          if (predicate != null)
          {
              query = query.Where(predicate);
          }
  
  
          if (!String.IsNullOrEmpty(includeProperties))
          {
              var splitProps = includeProperties.Split(',');
              foreach (var prop in splitProps)
              {
                  query = query.Include(prop);
              }
          }
  
          if (orderBy != null)
          {
              return orderBy(query).ToList();
          }
  
          return query.ToList();
      }
  
      public void DeleteItemsById(IEnumerable&lt;int&gt; ids)
      {
  
          var items = ids.Select(i =&gt; _set.Find(i));
  
          DeleteItems(items);
      }
  
      public void DeleteItem(T item)
      {
          _set.Remove(item);
      }
  
      public void DeleteItems(IEnumerable&lt;T&gt; items)
      {
          _context.Set&lt;T&gt;().RemoveRange(items);
      }
  
      public void Insert(T item)
      {
          _set.Add(item);
      }
  
      public void InsertItems(IEnumerable&lt;T&gt; items)
      {
          _set.AddRange(items);
      }
  
      public List&lt;T&gt; GetViewItems(Expression&lt;Func&lt;T, bool&gt;&gt; predicate)
      {
          IQueryable&lt;T&gt; query = _set.AsExpandable();
  
          return query.Where(predicate).ToList();
      }
  }
  </code></pre>
  
  <p>I am using this repository in services that relate to each object group involved in the sync, into which I inject the IUnitOfWork via the constructor:</p>
  
  <pre><code> private readonly IUnitOfWork _uow;
  
  public EntityDataService(IUnitOfWork uow, ICamsSfDTOMapper mapper)
      {
          _uow = uow;
      }
  </code></pre>
  
  <p>Then use the UoW to fetch repositories to performs queries:</p>
  
  <pre><code>var repo = _unitOfWork.PartyRepository;
  var p = repo.GetItems(p =&gt; Ids.Contains(someValue));
  </code></pre>
  
  <p>And when inserts or updates are made, I can call SaveChanges:</p>
  
  <pre><code>_unitOfWork.SaveChanges();
  </code></pre>
  
  <p>This works great for data retrieval, however for data persistence, I run into a snag.  On the local domain side, I want to iterate through objects one by one, saving changes or inserting and calling SaveChanges to persist.  If an error occurs, I store it in a result object that I log at the end of each sync step and continue onto the next object to do work on. </p>
  
  <p>However, as my app is currently structured, if a database exception occurs on SaveChanges, that validation error remains in the context until it is disposed.  Since this context is injected into each repository in the UoW class, it sticks around for what I presume is the life of the entire sync process.  </p>
  
  <p>I am using Autofac for DI in a WindowsService hosted using TopShelf and I'm registering my UoW as such:</p>
  
  <pre><code>builder.RegisterType&lt;UnitOfWork&gt;().As&lt;IUnitOfWork&gt;().WithParameter("context", new EntityModel());
  </code></pre>
  
  <p>Here are my questions:</p>
  
  <ol>
  <li>Should this question be posted to Code Review :)</li>
  <li>I feel like I should invert my repository with UoW, with UoW being passed into each repository and my repositories being passed into each service (a service can make use of more than one repository)</li>
  <li>Does it make sense to spin up a new DbContext for each SaveChanges and to have one DbContext (the one passed into UoW) as my read context and all other contexts new'ed up when SavingChanges?</li>
  </ol>
  
  <p>Any help would be appreciated.</p>