title: Trying to implement UnitOfWork in Entity framework
body: <p>I'm am trying to learn about the Unit Of Work pattern. However, I am having trouble finding an example that is not too simple or too complicated. So  decided to try and write something of my own taking from what I have read. I was wondering if what I have done is acceptable. I am trying to have the layers decoupled. The reasons I created the DatabaseManager was to avoid sending the context to the other layers. In the end this will be the DAL for a MVC application with a middle layer (business)</p>
  
  <p>Thanks for your input.</p>
  
  <p>Code:</p>
  
  <pre><code>public interface IDatabaseFactory : IDisposable
      {
          ObjectContext Get();
      }
  
      public class DatabaseFactory : Disposable, IDatabaseFactory
      {
          private ObjectContext _dataContext;
  
          #region IDatabaseFactory Members
  
          public ObjectContext Get()
          {
              return _dataContext ?? (_dataContext = (new MyMemberDatabase()));
          }
  
          #endregion
  
          protected override void DisposeCore()
          {
              if (_dataContext != null)
                  _dataContext.Dispose();
          }
      }
  
      public static class DatabaseManager
      {
          private static readonly Dictionary&lt;Guid, ObjectContext&gt; ContextLists = new Dictionary&lt;Guid, ObjectContext&gt;();
  
          public static ObjectContext GetContext(Guid id)
          {
              if (!ContextLists.ContainsKey(id))
              {
                  Guid newContextID = id;
                  ContextLists.Add(newContextID, new DatabaseFactory().Get());
              }
  
              return ContextLists[id];
          }
  
          public static void RemoveContext(Guid id)
          {
              if (ContextLists[id] != null)
  
                  ContextLists.Remove(id);
          }
      }
  
      public class Disposable : IDisposable
      {
          private bool _isDisposed;
  
          public void Dispose()
          {
              Dispose(true);
              GC.SuppressFinalize(this);
          }
  
          ~Disposable()
          {
              Dispose(false);
          }
  
          private void Dispose(bool disposing)
          {
              if (!_isDisposed &amp;&amp; disposing)
              {
                  DisposeCore();
              }
  
              _isDisposed = true;
          }
  
          protected virtual void DisposeCore()
          {
          }
      }
  
      public interface IUnitOfWork : IDisposable
      {
          Guid ContextID { get; }
          void Commit();
      }
  
      public class UnitOfWork : IUnitOfWork
      {
          private readonly Guid _contextID;
  
          public UnitOfWork()
          {
              _contextID = new Guid();
              _contextID = Guid.NewGuid();
          }
  
          #region IUnitOfWork Members
  
          public Guid ContextID
          {
              get { return _contextID; }
          }
  
          public void Commit()
          {
              DatabaseManager.GetContext(_contextID).SaveChanges();
          }
  
          public void Dispose()
          {
              DatabaseManager.RemoveContext(_contextID);
          }
  
          #endregion
      }
  
  
      public abstract class RepositoryBase&lt;T&gt; where T : class
      {
          private readonly IUnitOfWork _unitOfWork;
          private ObjectContext _context;
          private IObjectSet&lt;T&gt; _objectSet;
  
          private ObjectContext Context
          {
              get { return _context ?? (_context = DatabaseManager.GetContext(_unitOfWork.ContextID)); }
          }
  
          protected IObjectSet&lt;T&gt; ObjectSet
          {
              get { return _objectSet ?? (_objectSet = Context.CreateObjectSet&lt;T&gt;()); }
          }
  
          protected RepositoryBase(IUnitOfWork unitOfWork)
          {
              _unitOfWork = unitOfWork;
          }
  
      }
  class MemberRepository : RepositoryBase&lt;Member&gt;
      {
          public MemberRepository(IUnitOfWork unitOfWork) : base(unitOfWork)
          {
          }
  
  
          public virtual void Add(Member entity)
          {
              ObjectSet.AddObject(entity);
          }
  
          public virtual void Delete(Member entity)
          {
              ObjectSet.DeleteObject(entity);
          }
  
          public virtual IEnumerable&lt;Member&gt; GetAll()
          {
              return ObjectSet.AsEnumerable();
          }
  
      }
  </code></pre>
  
  <p>EDIT: New Code</p>
  
  <pre><code>public  interface IMemberRepository : IRepository
  {
      void Add(Member entity);
      void Delete(Member entity);
      IEnumerable&lt;Member&gt; GetAll();
  }
  public interface IRepository
  {
      IUnitOfWork UnitOfWork { get; }
  }
  public interface IUnitOfWork : IDisposable
  {
      void Commit();
  }
  
  public class DatabaseFactory : Disposable, IDisposable
  {
      private ObjectContext _dataContext;
  
      public ObjectContext Get()
      {
          return _dataContext ?? (_dataContext = (new MyMemberDatabase()));
      }
  
      protected override void DisposeCore()
      {
          if (_dataContext != null)
              _dataContext.Dispose();
      }
  }
  public static class DatabaseManager
  {
      private static readonly Dictionary&lt;Guid, ObjectContext&gt; ContextLists = new Dictionary&lt;Guid, ObjectContext&gt;();
  
      public static ObjectContext GetContext(Guid id)
      {
          if (!ContextLists.ContainsKey(id))
          {
              Guid newContextID = id;
              ContextLists.Add(newContextID, new DatabaseFactory().Get());
          }
          return ContextLists[id];
      }
  
      public static void RemoveContext(Guid id)
      {
          if (ContextLists[id] != null)
              ContextLists.Remove(id);
      }
  }
  public class Disposable : IDisposable
  {
      private bool _isDisposed;
  
      public void Dispose()
      {
          Dispose(true);
          GC.SuppressFinalize(this);
      }
  
      ~Disposable()
      {
          Dispose(false);
      }
  
      private void Dispose(bool disposing)
      {
          if (!_isDisposed &amp;&amp; disposing)
          {
              DisposeCore();
          }
  
          _isDisposed = true;
      }
  
      protected virtual void DisposeCore()
      {
      }
  }
  public class UnitOfWork : IUnitOfWork
  {
      private readonly Guid _contextID;
  
      public UnitOfWork()
      {
          _contextID = new Guid();
          _contextID = Guid.NewGuid();
      }
  
      #region IUnitOfWork Members
  
      internal Guid ContextID
      {
          get { return _contextID; }
      }
  
      public void Commit()
      {
          DatabaseManager.GetContext(_contextID).SaveChanges();
      }
  
      public void Dispose()
      {
          DatabaseManager.RemoveContext(_contextID);
      }
  
      #endregion
  }
  public abstract class RepositoryBase&lt;T&gt; : IRepository where T : class
  {
      private readonly UnitOfWork _unitOfWork;
      private ObjectContext _context;
      private IObjectSet&lt;T&gt; _objectSet;
  
      public IUnitOfWork UnitOfWork
      {
          get { return _unitOfWork; }
      }
  
      private ObjectContext Context
      {
          get { return _context ?? (_context = DatabaseManager.GetContext(_unitOfWork.ContextID)); }
      }
  
      protected IObjectSet&lt;T&gt; ObjectSet
      {
          get { return _objectSet ?? (_objectSet = Context.CreateObjectSet&lt;T&gt;()); }
      }
  
      protected RepositoryBase(IUnitOfWork unitOfWork)
      {
          _unitOfWork = (UnitOfWork)unitOfWork;
      }
  
      protected RepositoryBase()
      {
          _unitOfWork = new UnitOfWork();
      }
  }
  public class MemberRepository :  RepositoryBase&lt;Member&gt; ,IMemberRepository
  {
      public MemberRepository(IUnitOfWork unitOfWork) : base(unitOfWork)
      {
      }
  
      public MemberRepository():base()
      {
      }
  
      public virtual void Add(Member entity)
      {
          ObjectSet.AddObject(entity);
      }
  
      public virtual void Delete(Member entity)
      {
          ObjectSet.DeleteObject(entity);
      }
  
      public virtual IEnumerable&lt;Member&gt; GetAll()
      {
          return ObjectSet.AsEnumerable();
      }
  }
  </code></pre>