title: I just implemented a Unit Of Work pattern on top of Entity Framework using generic Repositories. What did I actually accomplish?
body: <p>If you don't care about the code I wrote and just want to have a discussion about abstracting existing abstractions... skip to the last 3 paragraphs.</p>
  
  <p>I was introduced to the idea of Repositories and the Unit Of Work on top of Entity Framework via a Pluralsight lesson I was watching. I also stubmled upon Microsoft's own page detailing this process: <a href="http://www.asp.net/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application" rel="nofollow">http://www.asp.net/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application</a></p>
  
  <p>So I decided to try it out. I set out to write my own Unit Of Work class with generic Repositories on top of Entity Framework, making absolutely everything along the way utilize interfaces so I could inject my own mocks for testing.</p>
  
  <p>First things first, for this exercise I chose to make a simple Blog application.</p>
  
  <p>So I started with the DbContext. Gotta make sure I use an interface!</p>
  
  <pre><code>    public interface ISimpleBlogContext : IDisposable
  {
      IDbSet&lt;Blog&gt; Blogs { get; }
      IDbSet&lt;Post&gt; Posts { get; }
  
      void SaveChanges();
      IDbSet&lt;T&gt; Set&lt;T&gt;() where T : class;
      DbEntityEntry Entry&lt;T&gt;(T entity) where T : class;
  }
  </code></pre>
  
  <p>I'm sure everybody knows what the IDbSets are for, but the SaveChanges, Set, and Entry methods might look a bit out of place. Don't worry, we'll get to those later.</p>
  
  <p>So now I hooked up my interface into an actual concrete DbContext :</p>
  
  <pre><code>    public class SimpleBlogContext : DbContext, ISimpleBlogContext
  {
      public SimpleBlogContext() {
          Database.SetInitializer&lt;SimpleBlogContext&gt;(new DropCreateDatabaseAlways&lt;SimpleBlogContext&gt;());
      }
  
      public IDbSet&lt;Blog&gt; Blogs { get; set; }
      public IDbSet&lt;Post&gt; Posts { get; set; }
  
      public DbEntityEntry Entry&lt;T&gt;(T entity) where T : class
      {
          return Entry&lt;T&gt;(entity);
      }
  
      void ISimpleBlogContext.SaveChanges()
      {
          SaveChanges();
      }
  
      IDbSet&lt;T&gt; ISimpleBlogContext.Set&lt;T&gt;()
      {
          return Set&lt;T&gt;();
      }
  </code></pre>
  
  <p>The database initializer is just ensuring that for this test application the database is dropped and recreated each time I run the app. This was just an exercise and not a real app after all. You can see the SaveChanges, Set, and Entry methods implemented here, and they're all nothing more than wrappers for the DbContext methods of the same name.</p>
  
  <p>So now on to the repositories...</p>
  
  <p>I wasn't going to re-write virtually the same repository code for every entity I might add to my application (although in this case I'll only wind up using one repository), so I made a generic repository. Don't skip the interface!</p>
  
  <pre><code>    public interface IGenericRepository&lt;T&gt;
      where T : class 
  {
      IEnumerable&lt;T&gt; GetAll();
      T GetById(object id);
      IEnumerable&lt;T&gt; GetByExpression(Expression&lt;Func&lt;T, bool&gt;&gt; expression);
      void Add(T entity);
      void Delete(T entity);
      void Update(T entity);
  }
  </code></pre>
  
  <p>and the concrete version... (notice I'm using my ISimpleBlogContext here instead of a concrete DbContext class because I want to be able to test all the things. Also, now you know why I had to write those Set, Entry, and SaveChanges methods in my ISimpleBlogContext interface)</p>
  
  <pre><code>    public class GenericRepository&lt;T&gt; : IGenericRepository&lt;T&gt;
      where T : class 
  {
  
      public GenericRepository(ISimpleBlogContext context)
      {
          this.context = context;
      }
  
      private ISimpleBlogContext context;
  
      public void Add(T entity)
      {
          context.Set&lt;T&gt;().Add(entity);
      }
  
      public void Delete(T entity)
      {
          context.Set&lt;T&gt;().Remove(entity);
      }
  
      public IEnumerable&lt;T&gt; GetAll()
      {
          return context.Set&lt;T&gt;().ToList&lt;T&gt;();
      }
  
      public IEnumerable&lt;T&gt; GetByExpression(Expression&lt;Func&lt;T, bool&gt;&gt; expression)
      {
          return context.Set&lt;T&gt;().Where&lt;T&gt;(expression).ToList&lt;T&gt;();
      }
  
      public T GetById(object id)
      {
          return context.Set&lt;T&gt;().Find(id);
      }
  
      public void Update(T entity)
      {
          context.Entry(entity).State = EntityState.Modified;
      }
  }
  </code></pre>
  
  <p>And now finally, the Unit Of Work class</p>
  
  <pre><code>    public class UnitOfWork : IDisposable
  {
  
      public void Dispose()
      {
          if (context != null)
          {
              context.Dispose();
              context = null;
          }
      }
      public UnitOfWork()
      {
          context = new SimpleBlogContext();
      }
  
      public UnitOfWork(ISimpleBlogContext context)
      {
          this.context = context;
      }
  
      private ISimpleBlogContext context;
  
      public GenericRepository&lt;TEntity&gt; GetRepository&lt;TEntity&gt;() where TEntity : class
      {
          return new GenericRepository&lt;TEntity&gt;(context);
      }
  
      public void Save()
      {
          context.SaveChanges();
      }
  
  }
  </code></pre>
  
  <p>I'm still allowing an ISimpleBlogContext to be passed in via the overloaded constructor, but the default constructor is where we finally get our concrete SimpleBlogContext DbContext from.</p>
  
  <p>So now I just have to test all this. So I wrote a simple Console application which does nothing more than generate a couple of fake blogs with a couple of fake posts and save them using the Unit Of Work class. Then it loops the blogs and posts and prints them out so I can verify that they were actually saved to the database.</p>
  
  <p>P.S. Jake is my dog in case you're wondering about the barking...</p>
  
  <pre><code>    class Program
  {
      static void Main(string[] args)
      {
          UnitOfWork unitOfWork = new UnitOfWork();
  
          GenericRepository&lt;Blog&gt; blogRepository = unitOfWork.GetRepository&lt;Blog&gt;();
  
          Blog paulsBlog = new Blog()
          {
              Author = "Paul",
              Posts = new List&lt;Post&gt;()
              {
                  new Post()
                  {
                      Title = "My First Post",
                      Body = "This is my first post"
                  },
                  new Post()
                  {
                      Title = "My Second Post",
                      Body = "This is my second post"
                  }
              }
          };
  
  
          Blog jakesBlog = new Blog()
          {
              Author = "Jake",
              Posts = new List&lt;Post&gt;()
              {
                  new Post()
                  {
                      Title = "Dog thoughts",
                      Body = "Bark bark bark"
                  },
                  new Post()
                  {
                      Title = "I like barking",
                      Body = "Bark bark bark"
                  }
              }
          };
  
  
          blogRepository.Add(paulsBlog);
          blogRepository.Add(jakesBlog);
          unitOfWork.Save();
  
          List&lt;Blog&gt; blogs = blogRepository.GetAll() as List&lt;Blog&gt;;
  
          foreach (Blog blog in blogs)
          {
              System.Console.WriteLine("ID: {0}, Author: {1}\n", blog.Id, blog.Author);
              if (blog.Posts != null &amp;&amp; blog.Posts.Count &gt; 0)
              {
                  foreach (Post post in blog.Posts)
                  {
                      System.Console.WriteLine("Posted at: {0}, Title: {1}, Body: {2}", post.PostTime, post.Title, post.Body);
  
                  }
              }
              else
              {
                  System.Console.WriteLine("No posts");
              }
              System.Console.WriteLine("\n");
          }
      }
  }
  </code></pre>
  
  <p>It works. Yay!</p>
  
  <p>My question, however, is simply... what did I gain exactly by doing any of this?</p>
  
  <p>Isn't DbContext already a Unit Of Work and DbSet is already a repository? It seems all I did was write a really elaborate wrapper for both of those things with no added functionality at all. You might say that it's more test-friendly since everything is using interfaces, but with mocking frameworks like Moq it's already possible to mock a DbSets and DbContexts. My repositories are generic so there is literally zero functionality that is specific to business logic. The Unit Of Work class is just a wrapper for DbContext and the generic Repositories are just wrappers for DbSet.</p>
  
  <p>Can somebody explain to me why anybody would do this? I watched a ~4 hour Pluralsight lesson on this, plus went through all the trouble of actually doing it myself, and I still don't get it.</p>