Entity Framework – Generic Repository Pattern – Part 2

In the previous post I wrote about an implementation of the Generic Repository pattern for EF. There is so much data on the web that it is difficult to understand what might actually work for you. All of this can drive you Crazy. Throw in my version of crazy as well Crazy2

Now that you have checked out the links and gone crazy reading how we all wanted a code review for this, it tells you the developer about the levels of confusion this pattern can create. One of my first thoughts was something like this Honestly, I don’t even remember what my exact thoughts were when I was prototyping the code.

In Part1 I did say that I will highlight some of the issues that I faced (remember YMMV). I didn’t do TDD for this ( sue me 🙂 ).

  • Testing is not as pain-free as it seems. What layers to test and how to test them ?
    After all of this code is for separating components and making life easier in the long run by increasing our confidence in the code.
    If EF is already a UoW and Repository then what are doing building a layer on top of this ?
  • We end up having a service layer anyway since our application logic is often non trivial and needs to be kept separate. Then the real fun begins with tests.
  • Mocking EF is a pain since you don’t have an IDbContext available. Get your fake data in there , then mock the repository and then mock the repository methods, then if you want to mock something like Includes() you will have some real fun. The idea is not mock EF, but even checking anything that sits on top of it can become an exercise in itself.
    After writing the tests, I can confidently say that my confidence in my code had not increased the manner I had expected (you bet this confidence thing is funny business) . I often had the feeling of buyer’s remorse.
  • It felt like I was on the wrong path. What do we really care about ? We need to get our data in and out of our database. That is it. How does making an abstraction help? It does not help that much. We are working exactly with the IQueryable that EF gives us back. Some implementations also have methods like FindById(..) , SortBy(..) etc…
    We need to concentrate on queries in our application. Make queries first class in your application.
  • Was all of this useless ? No, not quite. Implementing the Repository Pattern this way is, the pattern is not useless.
    We leak our data access technology Entity Framework into the Application Layer. A UnitOfWork driven implementation is actually very useful.
    I have not given that a go in code but here is something to start with Repository Pattern

In conclusion, it was both fun and enriching to hit roadblocks and see why the developers are moving to and from the Repository Pattern. I was working with EF6 and that came with its fair share of headaches. I will blog about that soon. Stay hungry, stay awesome.

Advertisements

Entity Framework – Generic repository Pattern – Part 1

The generic repository pattern has been a matter of discussion on the forums and SO. Developers are not convinced that it solves a problem, yet everyday SO has more questions about the pattern. Clearly, something is not right. I tried to implement the pattern in a way I thought fit. I changed my mind a million times during the process, that tells you that the process was not smooth. You can find several implementations of the pattern scattered all over the internet. I will not pass a opinion on the pattern. I would rather tell you what issues I faced and I how solved (or not) them.

First I created an IRepository and IUnitOfwork

   public interface IRepository
    {
        T Add(T entity);

        T Remove(T entity);

        T Update(T entity);

        IQueryable Query();        
    }

    public interface IUnitOfWork : IDisposable
    {
        void Commit();
    }

Next, let’s get the EF specific implementation up and running.


/// <summary>
    /// A EFRepository represents the repository for performing operations on the
    /// Entity using the EntityFramework.
    /// </summary>
    /// <typeparam name="T">T is the Entity</typeparam>
    public class EFRepository<T> : IRepository<T> where T : class
{
        /// <summary>
        /// This is set in the constructor and provides access to the underlying EntityFramework methods
        /// </summary>
        private DbSet<T> _dbSet;

        /// <summary>
        /// The context for working with the EntityFramework. This is set in the constructor.
        /// </summary>
        private DbContext _dataContext;

        /// <summary>
        /// Initialises a new instance of Repository for <see cref="T"/>
        /// </summary>
        /// <param name="unitOfWork">IUnitOfWork</param>
        /// <param name="dataContext">DbContext</param>
        /// <exception cref="ArgumentNullException">Throws ArgumentNullException if any of the arguments is null</exception>
        public EFRepository(IUnitOfWork unitOfWork, DbContext dataContext)
        {
            if (unitOfWork == null)
            {
                throw new ArgumentNullException("unitOfWork", "unitOfWork cannot be null");
            }

            if (dataContext == null)
            {
                throw new ArgumentNullException("dataContext", "dataContext cannot be null");
            }

            var EfUnitOfWork = unitOfWork as EFUnitOfWork;            
            _dataContext = dataContext;
            _dbSet = _dataContext.Set<T>();
        }

        /// <summary>
        /// Adds the specified Entity to the DbSet of the context.
        /// The Entity is inserted only when UnitOfWork is commited.
        /// </summary>
        /// <param name="item">The Entity to be added</param>
        /// <returns>The added Entity</returns>
        public T Add(T item)
        {
            return _dbSet.Add(item);
        }

        /// <summary>
        /// Removes the specified Entity from the DbSet of the context.
        /// The Entity is removed only when UnitOfWork is commited.
        /// </summary>
        /// <param name="item">The Entity to be removed</param>
        /// <returns>The Entity removed from the underlying DbSet</returns>
        public T Remove(T item)
        {
            return _dbSet.Remove(item);
        }

        /// <summary>
        /// Removes the specified Entity from the DbSet of the context.
        /// The Entity is removed only when UnitOfWork is commited.
        /// </summary>
        /// <param name="item">The Entity to be updated</param>
        /// <returns>the Entity removed from the underlying DbSet</returns>
        public T Update(T item)
        {
            var updated = _dbSet.Attach(item);
            _dataContext.Entry(item).State = EntityState.Modified;
            return updated;
        }

        /// <summary>
        /// Provides the caller with the underlying DbSet.
        /// </summary>
        /// <returns>An IQueryable to run queries against the underlying DbSet</returns>
        public IQueryable<T> Query()
        {
            return _dbSet;
        }

Follow this up with an implementation of EFUnitOfWork


/// <summary>
    /// Represents an IUnitOfWork for Entity Framework
    /// </summary>
    public class EFUnitOfWork : IUnitOfWork
    {
        /// <summary>
        /// The DbContext for the UnitOfWork
        /// </summary>
        private DbContext _context;

        /// <summary>
        /// Private field to check if the context has been disposed
        /// </summary>
        private bool _disposed;

        /// <summary>
        /// Initialises a new instance of EfUnitOfWork <see cref="EFUnitOfWork"/>
        /// </summary>
        /// <param name="context">DbContex for the UnitOfWork</param>
        public EFUnitOfWork(DbContext context)
        {
            if (context == null)
            {
                throw new UnitOfWorkException();
            }

            _context = context;
        }

        /// <summary>
        /// Method to e called when a UnitOfWork is to be committed.
        /// </summary>
        public void Commit()
        {
            _context.SaveChanges();
        }

        // Implement IDisposable.       
        public void Dispose()
        {
            Dispose(true);

            // Take yourself off the Finalization queue to prevent finalization code for object from executing a second time.
            GC.SuppressFinalize(this);
        }
       
        protected virtual void Dispose(bool disposing)
        {
            // Check to see if Dispose has already been called.
            if (!_disposed)
            {
                // If disposing equals true, dispose all managed and unmanaged resources.
                if (disposing)
                {
                    // Dispose managed resources.
                    if (_context != null)
                    {
                        _context.Dispose();
                    }
                }             
            }

            _disposed = true;
        }
    }

    [Serializable]
    public class UnitOfWorkException : Exception
    {
        public override string Message
        {
            get
            {
                return "The parameter must be EFUnitOfWork";
            }
        }
    }

The above code is at Github
Are there alternatives ?
Oh yes plenty. Some just differ in implementation details , but others differ in philosophy altogether.
Next time I will blog about a different one that I thought of initially. Then later I will write about the problems we face.
Pick and choose what fits.