Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic Repository Pattern with UnitOfWork Pattern

I am trying to implement a generic repository pattern. I found this site which I think its well explained. http://www.tugberkugurlu.com/archive/generic-repository-pattern-entity-framework-asp-net-mvc-and-unit-testing-triangle

My purpose is to save the developers some time and keystrokes and I know this will help me.

So I have 2 questions:
1. Is this a good approach or not, will I have some problems in the future?
2. How can I combine it with Unitofwork pattern?, I cant create an instance of the abstract class of course, so the following code its invalid.

public class UnitOfWork : IDisposable
    {
        #region Private fields
        private readonly MyCompanyContext _context = new MyCompanyContext();
        private GenericRepository<MyCompanyContext, Task> _taskRepository;

        public GenericRepository<MyCompanyContext, Task> TaskRepository
        {
            get
            {
                return _taskRepository ??
                         (_taskRepository = new GenericRepository<MyCompanyContext, Task>());
            }
        }




namespace MyCompany.DAL.Repository
{
    public interface IGenericRepository<T> where T : class
    {
        IQueryable<T> GetAll();
        IQueryable<T> FindBy(Expression<Func<T, bool>> predicate);
        void Add(T entity);
        void Delete(T entity);
        void Edit(T entity);
        void Save();
    }

    public abstract class GenericRepository<C, T> :
    IGenericRepository<T>
        where T : class
        where C : DbContext, new()
    {

        private C _entities = new C();
        public C Context
        {

            get { return _entities; }
            set { _entities = value; }
        }

        public virtual IQueryable<T> GetAll()
        {

            IQueryable<T> query = _entities.Set<T>();
            return query;
        }

        public IQueryable<T> FindBy(System.Linq.Expressions.Expression<Func<T, bool>> predicate)
        {
            IQueryable<T> query = _entities.Set<T>().Where(predicate);
            return query;
        }

        public virtual void Add(T entity)
        {
            _entities.Set<T>().Add(entity);
        }

        public virtual void Delete(T entity)
        {
            _entities.Set<T>().Remove(entity);
        }

        public virtual void Edit(T entity)
        {
            _entities.Entry(entity).State = System.Data.EntityState.Modified;
        }

        public virtual void Save()
        {
            _entities.SaveChanges();
        }
    }
}
like image 522
Luis Valencia Avatar asked Jul 03 '12 08:07

Luis Valencia


People also ask

What is generic repository pattern?

It is a data access pattern that prompts a more loosely coupled approach to data access. We create a generic repository, which queries the data source for the data, maps the data from the data source to a business entity, and persists changes in the business entity to the data source.

Should I use repository pattern with dapper?

Large-scale, complex projects benefit the most from readability improvments, and when using Dapper and C# the Dapper Base Repository pattern allows for better code readability and a single point of failure by creating a base class with generic methods that allow for querying and execution against a SQL database.

What is the use of Unitofwork?

The unit of work class serves one purpose: to make sure that when you use multiple repositories, they share a single database context. That way, when a unit of work is complete you can call the SaveChanges method on that instance of the context and be assured that all related changes will be coordinated.


2 Answers

There are several opinions regarding repositories, but after trying various repository implementations in production for couple years myself, I agree with Ayende's opinion, that repository, especially generic, is redundant abstraction layer.

I liked very much this course: http://www.pluralsight-training.net/microsoft/Courses/TableOfContents/linq-architecture

It walked through most possible solutions and explained goods and bads.

What we're using right now is very thin abstraction over datacontext, just to overcome Linq2Sql testability issues, which are irrelevant in most cases when using EF.

like image 106
Giedrius Avatar answered Oct 26 '22 22:10

Giedrius


With a lot of effort you might get that working, but I wonder if the effort is really worth it? I've seen implementations like this before, and they really struggle when attempting to manage many-to-many relationships (have a think about how you'd manage that in your scenario). You are using Entity Framework, an ORM right? ORMs like Entity Framework and nHibernate are designed to abstract the database implementation from application code, so what is the purpose of adding yet another abstraction above it to manage entities at such a granular level? If it's a question of testing, then you can use a mocking framework to mock the context, thus removing the need for an actual database during testing. If however, for architectural or security reasons you are seeking to remove interactions with a db context from your app code, I'd recommend for pragmatism using an implementation of the command pattern over the top of the entity framework. I've needed to do this on a larger scale enterprise (banking) application where for security reasons (rightly or wrongly) we were absolutely not allowed to have a db connection in our application code.

like image 29
Toby Couchman Avatar answered Oct 26 '22 22:10

Toby Couchman