Thought 1
public interface IRepository<T> : IDisposable where T : class
{
IQueryable<T> Fetch();
IEnumerable<T> GetAll();
IEnumerable<T> Find(Func<T, bool> predicate);
T Single(Func<T, bool> predicate);
T First(Func<T, bool> predicate);
void Add(T entity);
void Delete(T entity);
void SaveChanges();
}
with the above approach I will go like Repository and then have a Repository with the implementation of methods written above.
I think this frees my tests from DbContext dependency.
Thought 2
public class RepositoryBase<TContext> : IDisposable where TContext : DbContext, new()
{
private TContext _DataContext;
protected virtual TContext DataContext
{
get
{
if (_DataContext == null)
{
_DataContext = new TContext();
}
return _DataContext;
}
}
public virtual IQueryable<T> GetAll<T>() where T : class
{
using (DataContext)
{
return DataContext.Set<T>();
}
}
public virtual T FindSingleBy<T>(Expression<Func<T, bool>> predicate) where T : class
{
if (predicate != null)
{
using (DataContext)
{
return DataContext.Set<T>().Where(predicate).SingleOrDefault();
}
}
else
{
throw new ArgumentNullException("Predicate value must be passed to FindSingleBy<T>.");
}
}
public virtual IQueryable<T> FindAllBy<T>(Expression<Func<T, bool>> predicate) where T : class
{
if (predicate != null)
{
using (DataContext)
{
return DataContext.Set<T>().Where(predicate);
}
}
else
{
throw new ArgumentNullException("Predicate value must be passed to FindAllBy<T>.");
}
}
public virtual IQueryable<T> FindBy<T, TKey>(Expression<Func<T, bool>> predicate,Expression<Func<T, TKey>> orderBy) where T : class
{
if (predicate != null)
{
if (orderBy != null)
{
using (DataContext)
{
return FindAllBy<T>(predicate).OrderBy(orderBy).AsQueryable<T>(); ;
}
}
else
{
throw new ArgumentNullException("OrderBy value must be passed to FindBy<T,TKey>.");
}
}
else
{
throw new ArgumentNullException("Predicate value must be passed to FindBy<T,TKey>.");
}
}
public virtual int Save<T>(T Entity) where T : class
{
return DataContext.SaveChanges();
}
public virtual int Update<T>(T Entity) where T : class
{
return DataContext.SaveChanges();
}
public virtual int Delete<T>(T entity) where T : class
{
DataContext.Set<T>().Remove(entity);
return DataContext.SaveChanges();
}
public void Dispose()
{
if (DataContext != null) DataContext.Dispose();
}
}
I could now have CustomerRepository : RepositoryBase<Mycontext>,ICustomerRepository
ICustomerRepository
gives me the option of defining stuff like GetCustomerWithOrders
etc...
I am confused as to which approach to take. Would need help through a review on the implementation first then comments on which one will be the easier approach when it comes to Testing and extensibility.