5

I've just seen realisation of GenericRepository:

namespace ContosoUniversity.DAL
{
    public class GenericRepository<TEntity> where TEntity : class
    {
        internal SchoolContext context;
        internal DbSet<TEntity> dbSet;

        public GenericRepository(SchoolContext context)
        {
            this.context = context;
            this.dbSet = context.Set<TEntity>();
        }

        public virtual IEnumerable<TEntity> Get(
            Expression<Func<TEntity, bool>> filter = null,
            Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
            string includeProperties = "")
        {
            IQueryable<TEntity> query = dbSet;

            if (filter != null)
            {
                query = query.Where(filter);
            }

            foreach (var includeProperty in includeProperties.Split
                (new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
            {
                query = query.Include(includeProperty);
            }

            if (orderBy != null)
            {
                return orderBy(query).ToList();
            }
            else
            {
                return query.ToList();
            }
        }

        public virtual TEntity GetByID(object id)
        {
            return dbSet.Find(id);
        }

        public virtual void Insert(TEntity entity)
        {
            dbSet.Add(entity);
        }

        public virtual void Delete(object id)
        {
            TEntity entityToDelete = dbSet.Find(id);
            Delete(entityToDelete);
        }

        public virtual void Delete(TEntity entityToDelete)
        {
            if (context.Entry(entityToDelete).State == EntityState.Detached)
            {
                dbSet.Attach(entityToDelete);
            }
            dbSet.Remove(entityToDelete);
        }

        public virtual void Update(TEntity entityToUpdate)
        {
            dbSet.Attach(entityToUpdate);
            context.Entry(entityToUpdate).State = EntityState.Modified;
        }
    }
}

here: http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application and i think it's really nice, but i'd like to ask you a question. what the pros and cons of this approach with separate realisation (each entity repository in separate class)?

3 Answers3

1

Even if you decide you need to have concrete Repository classes for each entity, it still makes absolute sense to, at a minimum, use a generic repository as the base so you are not duplicating code, and can test common functionality in one place.

Realistically, there are no cons to this practice. If you need to fudge how one of the methods work for a specific entity, you just override it, fix it, and make sure it's covered in a unit test.

moribvndvs
  • 42,191
  • 11
  • 135
  • 149
  • So, is it a 'silver bullet' for repository pattern realisation? –  Jun 19 '12 at 11:52
  • "Silver bullet" is a loaded word... no, I can't say it's that; There is merit to the argument that it can become a leaky abstraction, in that, to efficiently complete a task, you may need to use ORM-specific functionality, and exposing that functionality generically can be a nightmare. However, 95% of the time, I don't need that, and as @Steven says in his answer, they are (IMHO) too useful to be ignored. See my answer here for more details, and how I handle the 5% of situations that are tricky with generic repositories http://stackoverflow.com/a/10925510/64750 – moribvndvs Jun 19 '12 at 12:06
1

This is more personal taste than anything else. Personally I don't like the term Repository because it's too generic and the meaning/purpose of the repository has been lost. I find repositories are often generic and repetitive as if every entity needs it's own repo. and then the repo gets too many one off methods for querying. pretty soon you end up with a god class for data access. This has been my experience.

with the generic repo you can use inheritance to sub-class to specific entities for on-off queries. I prefer composition over inheritance, so another reason why I avoid the term/use of repos.

instead I like to think of data access as query (read) & command (write) objects. where each object has 1 method to retrieve a specific projection (query) of the data or modify the persisted data (command).

in the end so long as you & your team understand the architecture and the code is maintainable, you have a solid solution. It's not really good or bad.

Jason Meckley
  • 7,589
  • 1
  • 24
  • 45
1

There are several opinions about the use of generic decorators. There are basically two camps. The first camp finds the generic repository a leaky abstraction, which means you are often aren't really abstracting the datasource with it. It should therefore not be used at all. Read for instance this answer.

I'm in the second camp. I know it is a leaky abstraction, but a generic repository (especially with IQuerable support), just leads to too expressive and testable code, to be ignored. I've written an article about generic repositories. It's an alternative approach to approach your link points add. It gives you a different approach to generic repositories, with the focus on maintainability and testability. You may find it useful.

Steven
  • 166,672
  • 24
  • 332
  • 435