I am working on a generic repository. And I wondered if anyone could give some feedback on it.
Interface for DbContext:
public interface IDbContext
{
IDbSet<T> Set<T>() where T : class;
DbEntityEntry Entry<T>(T entity) where T : class;
void SaveChanges();
}
Context class
public class BookContext : DbContext, IDbContext
{
public BookContext()
: base("BookDB")
{ }
public new IDbSet<T> Set<T>() where T : class
{
return base.Set<T>();
}
public new DbEntityEntry Entry<T>(T entity) where T : class
{
return base.Entry(entity);
}
public new void SaveChanges()
{
base.SaveChanges();
}
}
Repository interface
public interface IRepository<T>
{
IQueryable<T> FindAll();
IQueryable<T> Find(Expression<Func<T, bool>> predicate);
T FindById(int id);
void AddOrUpdate(T entity);
void Remove(T entity);
}
Repository implementation
public class Repository<T> : IRepository<T>
where T : class, IEntity
{
protected readonly IDbContext Context;
public Repository(IDbContext context)
{
Context = context;
}
public IQueryable<T> FindAll()
{
return Context.Set<T>();
}
public IQueryable<T> Find(Expression<Func<T, bool>> predicate)
{
return Context.Set<T>().Where(predicate);
}
public T FindById(int id)
{
return Context.Set<T>().SingleOrDefault(o => o.Id == id);
}
public void AddOrUpdate(T entity)
{
if (entity == null)
throw new ArgumentNullException("entity");
if (entity.Id == 0)
{
Context.Set<T>().Add(entity);
}
else
{
Context.Entry(entity).State = EntityState.Modified;
}
Context.SaveChanges();
}
public void Remove(T entity)
{
if (entity == null)
throw new ArgumentNullException("entity");
Context.Set<T>().Remove(entity);
Context.SaveChanges();
}
}
Additional repository
public interface IBookRepository
{
Book FindByIsbn(string isbn);
IQueryable<Book> FindByAuthor(Author author);
}
Book repo implementaion
public class BookRepository : Repository<Book>, IBookRepository
{
public BookRepository(IDbContext context) : base(context)
{
}
public Book FindByIsbn(string isbn)
{
return Context.Set<Book>().SingleOrDefault(b => b.Isbn.Equals(isbn));
}
public IQueryable<Book> FindByAuthor(Author author)
{
return Context.Set<Book>().Where(b => b.Author.Id == author.Id);
}
}
I am planning to use this repo with autofac IoC. I am not sure If I should use Unit of work pattern and should I make my repos disposable. Any feedback would be appreciated.