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();
}
}
}
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.