Generic Repository for Entity Framework 4.1

About six weeks ago I started playing with Microsoft Entity Framework, which just now recently went from RC to RTM. After browsing over sample after sample of terrible source code, yes something can be learned by looking at smelly code, I ran across a very unique way of implementing a Generic Repository. There were a few things about the code I did not care for and I have changed those things and posted the sample below.

I would like to give full credit to Sergey Barskiy for posting the original example of how to do this. Sergey is a Pro and I am well, a network guy learning to write C# code.

I am using Ninject to Inject the context in to the constructor of RepositoryBase. This works well and I strongly recommend using DI whenever possible. I am not going to get in to Ninject as there are many posts out there already that give better detail than i could.

I have also modified the GetDbSet method to use the injected context. Have fun with it, I did!

using System;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Reflection;

namespace Infrastructure.Repositories
{
 public interface IRepository:IDisposable
    {
        void CommitChanges();
        PropertyInfo GetDbSet(Type itemType);
        void Delete<T>(T item) where T : class, new();
        T Update<T>(T item) where T : class, new();
        IQueryable<T> Select<T>() where T : class, new();
        T Insert<T>(T item) where T : class, new();
    }

    public class RepositoryBase:IRepository
    {
        private readonly DbContext _context;
        public RepositoryBase(IContextFactory contextFactory)
        {
            _context = contextFactory.Create();
        }

        #region Implementation of IRepository

        public void CommitChanges()
        {
            _context.SaveChanges();
        }

        public IQueryable<T> Select<T>() where T: class,new()
        {
            PropertyInfo property = GetDbSet(typeof (T));
            DbSet<T> set = property.GetValue(_context, null) as DbSet<T>;
            return set;
        }

        public T Insert<T>(T item) where T: class,new()
        {
            DbSet<T> set = GetDbSet(typeof (T)).GetValue(_context, null) as DbSet<T>;
            set.Add(item);
            return item;
        }

        public T Update<T>(T item) where T : class,new()
        {
            DbSet<T> set = GetDbSet(typeof (T)).GetValue(_context, null) as DbSet<T>;
            set.Attach(item);
            _context.Entry(item).State = EntityState.Modified;
            return item;

        }

        public void Delete<T>(T item) where T: class,new()
        {
            DbSet<T> set = GetDbSet(typeof (T)).GetValue(_context, null) as DbSet<T>;
            var entry = _context.Entry(item);
            if(entry!=null)
            {
                entry.State = EntityState.Deleted;
            }
            else
            {
                set.Attach(item);
            }
            _context.Entry(item).State = EntityState.Deleted;
        }

        public PropertyInfo GetDbSet(Type itemType)
        {
            var properties = _context.GetType().GetProperties().Where(item => item.PropertyType.Equals(typeof (DbSet<>).MakeGenericType(itemType)));
            return properties.First();
        }

       #endregion
        #region Implementation of IDisposable

        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        /// <filterpriority>2</filterpriority>
        public void Dispose()
        {
            _context.Dispose();
        }

        #endregion
    }
}

About these ads

,

  1. Leave a comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: