 <p>The approach of this article is really something that can be become a pain, because you already have a generic repository and a generic IUnitOfWork in EF and creating the specific repository for each type just removes the benefit of the generic!</p> <p>I am posting here a sample of how i have a generic Repository and my IUnitOfWork, with this you can have a very nice repository!</p> <pre><code>public interface IUnitOfWork : IDisposable { void Save(); void Save(SaveOptions saveOptions); } public interface IRepository&lt;TEntity&gt; : IDisposable where TEntity : class { IUnitOfWork Session { get; } IList&lt;TEntity&gt; GetAll(); IList&lt;TEntity&gt; GetAll(Expression&lt;Func&lt;TEntity, bool&gt;&gt; predicate); bool Add(TEntity entity); bool Delete(TEntity entity); bool Update(TEntity entity); bool IsValid(TEntity entity); } </code></pre> <p>And the implementation something like:</p> <pre><code>public class Repository : Component, IRepository { protected DbContext session; public virtual IUnitOfWork Session { get { if (session == null) throw new InvalidOperationException("A session IUnitOfWork do repositório não está instanciada."); return (session as IUnitOfWork); } } public virtual DbContext Context { get { return session; } } public Repository(IUnitOfWork instance) { SetSession(instance); } public IList&lt;TEntity&gt; GetAll&lt;TEntity&gt;() where TEntity : class { return session.Set&lt;TEntity&gt;().ToList(); } public IList&lt;TEntity&gt; GetAll&lt;TEntity&gt;(Expression&lt;Func&lt;TEntity, bool&gt;&gt; predicate) where TEntity : class { return session.Set&lt;TEntity&gt;().Where(predicate).ToList(); } public bool Add&lt;TEntity&gt;(TEntity entity) where TEntity : class { if (!IsValid(entity)) return false; try { session.Set(typeof(TEntity)).Add(entity); return session.Entry(entity).GetValidationResult().IsValid; } catch (Exception ex) { if (ex.InnerException != null) throw new Exception(ex.InnerException.Message, ex); throw new Exception(ex.Message, ex); } } public bool Delete&lt;TEntity&gt;(TEntity entity) where TEntity : class { if (!IsValid(entity)) return false; try { session.Set(typeof(TEntity)).Remove(entity); return session.Entry(entity).GetValidationResult().IsValid; } catch (Exception ex) { if (ex.InnerException != null) throw new Exception(ex.InnerException.Message, ex); throw new Exception(ex.Message, ex); } } public bool Update&lt;TEntity&gt;(TEntity entity) where TEntity : class { if (!IsValid(entity)) return false; try { session.Set(typeof(TEntity)).Attach(entity); session.Entry(entity).State = EntityState.Modified; return session.Entry(entity).GetValidationResult().IsValid; } catch (Exception ex) { if (ex.InnerException != null) throw new Exception(ex.InnerException.Message, ex); throw new Exception(ex.Message, ex); } } public virtual bool IsValid&lt;TEntity&gt;(TEntity value) where TEntity : class { if (value == null) throw new ArgumentNullException("A entidade não pode ser nula."); return true; } public void SetSession(IUnitOfWork session) { SetUnitOfWork(session); } protected internal void SetUnitOfWork(IUnitOfWork session) { if (!(session is DbContext)) throw new ArgumentException("A instância IUnitOfWork deve um DbContext."); SetDbContext(session as DbContext); } protected internal void SetDbContext(DbContext session) { if (session == null) throw new ArgumentNullException("DbContext: instance"); if (!(session is IUnitOfWork)) throw new ArgumentException("A instância DbContext deve implementar a interface IUnitOfWork."); this.session = session; } } </code></pre>