Impemlmentation of Generic Repository Pattern and Unit of work with Entity Framework 2

I know this is may be a very old topic and heaps of resources can just come up with a simple Google search but it may worth also to consider this article as one of these resources :-)

Ok… I am a kind of person who likes to hit directly to the point, so I am not going to describe the repository pattern, unit of work or even how to use Entity framework here. However I will start directly with a walk-through sample on how to Implement a generic repository pattern using Entity Framework 6.

I ‘ll show how I’d like to organize my solution and how to structure the Data Access.

Usually I create a Data Access folder withing my solution and create three different projects underneath

+ Data Access

- Data Access Core

– Data Entity

– Data Framework

Data Framework

This project is to hold the Entity Framework model (*.edmx file), Nothing else.

Data Entity

Data Entity Project is to hold the entity classes which maps one to one to the database tables.

I prefer to use the T4 template to generate these Entity Classes.

Data Access Core

Core Project does contain the implementation of the Repository and Unit of work pattern

  1. I define three interfaces:
  • IRepository : this one holds all the generic repository methods as shown below
    /// <summary
    /// Generic Repository Interface
    /// </summary>
    /// <typeparam name="T">Dynamic parameter of type class</typeparam>
    public interface IRepository<T> where T : class
    {
        /// <summary>
        /// Set based on where condition
        /// </summary>
        /// <returns>The records matching the given condition</returns>
        IQueryable<T> GetQuery();

        /// <summary>
        /// Gets all entities
        /// </summary>        
        /// <returns>All entities</returns>
        IEnumerable<T> GetAll();

        /// <summary>
        /// Get Entity by Primary Key
        /// </summary>
        /// <param name="key">Primary Key</param>
        /// <returns></returns>
        T Get(object key);

        /// <summary>
        /// Finds all entities matching the predicate
        /// </summary>
        /// <param name="predicate">The filter clause</param>
        /// <returns>All entities matching the predicate</returns>
        IEnumerable<T> Find(Expression<Func<T, bool>> predicate);

        /// <summary>
        /// Adds a given entity to the context
        /// </summary>
        /// <param name="entity">The entity to add to the context</param>
        void Add(T entity);

        /// <summary>
        /// Deletes a given entity from the context
        /// </summary>
        /// <param name="entity">The entity to delete</param>
        void Delete(T entity);

        /// <summary>
        /// Update a given entity to the context
        /// </summary>
        /// <param name="entity">The entity to attach</param>
        void Update(T entity);

    }
  • IUnitOfWork: UnitOfwork is to handle the concurrency and transactions, According to Martin Fowler definition “the Unit of Work pattern “maintains a list of objects affected by a business transaction and coordinates the writing out of changes and the resolution of concurrency problems.”
   /// <summary>
    /// Unit Of Work Pattern
    /// </summary>
    public interface IUnitOfWork : IDisposable
    {

        /// <summary>
        /// Save into Database
        /// </summary>
        void Commit();

        /// <summary>
        /// Rollback Transaction
        /// </summary>
        void Rollback();

        /// <summary>
        /// Context Injection
        /// </summary>
        IContext Context { get;  }

    }
  • IContext: To be able to unit test our code, we need to introduce an interface to help to Moq the EF Context.
/// <summary>
    /// Context Interface
    /// </summary>
    public interface IContext : IDisposable
    {
        /// <summary>
        /// Database Context
        /// </summary>
        DbContext DbContext { get; }

        /// <summary>
        /// Generic Data Set
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        IDbSet<T> DbSet<T>() where T : class;
    }

2. Interfaces Implementation

  • Generic Repository Implementation
 /// <summary>
    /// Generic Repository Class
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class Repository<T> : IRepository<T> where T: class
    {
        private readonly IContext _context;
        private readonly IDbSet<T> _dbset;

        public Repository(IContext context)
        {
            if (context == null) return;
            _context = context;
            _dbset = context.DbSet<T>();
        }

        
        public IQueryable<T> GetQuery()
        {
            return _dbset;
        }

        
        public IEnumerable<T> GetAll()
        {
            return GetQuery().ToList();
        }

        public T Get(object key)
        {
            return _dbset.Find(key);
        }

        public IEnumerable<T> Find(Expression<Func<T, bool>> predicate)
        {
            return _dbset.Where(predicate);
        }

        public void Add(T entity)
        {
            _dbset.Add(entity);
        }

        public void Delete(T entity)
        {
            var entry = _context.DbContext.Entry(entity);
            entry.State = EntityState.Deleted;
        }

        public void Update(T entity)
        {
            var entry = _context.DbContext.Entry(entity);
            _dbset.Attach(entity);
            entry.State = EntityState.Modified;
        }
    }
}
  • Unit Of Work Implementation
 public class UnitOfWork : IUnitOfWork
    {
        private readonly IContext _context ;

        public UnitOfWork(IContext context)
        {
            _context = context;
        }

        /// <summary>
        /// Dispose
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        /// <summary>
        /// Commit to Database
        /// </summary>
        public void Commit()
        {
            _context.DbContext.SaveChanges();
        }

        /// <summary>
        /// Rollback Transaction
        /// </summary>
        public void Rollback()
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// Context
        /// </summary>
        public IContext Context
        {
            get { return _context; }
        }

        private bool _disposed;

        protected virtual void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                if (disposing)
                {
                    _context.DbContext.Dispose();
                }
            }
            _disposed = true;
        }
  • Context Implementation
 /// <summary>
    /// Context Concrete Class
    /// </summary>
    public class Context : IContext
    {
        /// <summary>
        /// Used to Inject the Entity Framework Context
        /// </summary>
        /// <param name="context"></param>
        public Context(DbContext context)
        {
            DbContext = context;
        }

        /// <summary>
        /// Dispose Context
        /// </summary>
        public void Dispose()
        {
            DbContext.Dispose();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        IDbSet<T> IContext.DbSet<T>()
        {
            return DbContext.Set<T>();
        }

        /// <summary>
        /// 
        /// </summary>
        public DbContext DbContext { get; private set; }

    }

 Now finished with the Patterns implementation, to start using this implementation inside your business objects,you simply will do something like that to retrieve data

var customerRep = IRepository<Customer>();
 var customers = customerRep.GetAll();

In the next article I will show how to structure your solution for medium and large projects. it will show how to make your solution testable, salable and maintainable using design patterns and design principles.

Impemlmentation of Generic Repository Pattern and Unit of work with Entity Framework
1 vote, 5.00 avg. rating (100% score)

2 thoughts on “Impemlmentation of Generic Repository Pattern and Unit of work with Entity Framework

  1. Reply Luis Martinez May 8,2014 5:52 am

    Great sample, can you publish the source code?

    and other qeustiong

    can u make other article consuming for the domain and prestantion layer.
    Is just to check the references

    • Reply Hazem Salem May 13,2014 9:58 am

      Hi Luis, Yes will do another article for whole solution and how this approach can be used along with Dependency injection and Unity IOC. Will attach the solution as well.
      Cheers,

Leave a Reply