Reputation: 309
I have a generic data access layer implemented by an interface that will be used by different modules with different DB context.
Here is the code:
public class GenericDataRepository<T> : IGenericDataRepository<T> where T : class
{
public virtual IList<T> Get(Func<T, bool> filter, int page, int pageSize, string[] includePaths = null, params SortExpression<T>[] sortExpressions)
{
List<T> list;
using (var context = new _DbContext())
{
IQueryable<T> dbQuery = context.Set<T>();
if (includePaths != null)
{
for (var i = 0; i < includePaths.Count(); i++)
{
dbQuery = dbQuery.Include(includePaths[i]);
}
}
if (filter != null)
{
dbQuery = dbQuery.Where(filter).AsQueryable();
}
IOrderedEnumerable<T> orderedQuery = null;
for (var i = 0; i < sortExpressions.Count(); i++)
{
if (i == 0)
{
if (sortExpressions[i].SortDirection == ListSortDirection.Ascending)
{
orderedQuery = dbQuery.OrderBy(sortExpressions[i].SortBy);
}
else
{
orderedQuery = dbQuery.OrderByDescending(sortExpressions[i].SortBy);
}
}
else
{
if (sortExpressions[i].SortDirection == ListSortDirection.Ascending)
{
orderedQuery = orderedQuery.ThenBy(sortExpressions[i].SortBy);
}
else
{
orderedQuery = orderedQuery.ThenByDescending(sortExpressions[i].SortBy);
}
}
dbQuery = orderedQuery.AsQueryable();
}
dbQuery = dbQuery.Skip(((int)page - 1) * (int)pageSize);
dbQuery = dbQuery.Take((int)pageSize);
list = dbQuery
.ToList<T>();
}
return list;
}
}
In this GenericDataRepository layer, I don't have DB context class. I want this GenericDataRepository to accept DB context as an incoming parameter from different calling module to perform operations written in Getting method.
You can see I use
using (var context = new _DbContext())
In getting method. I don't know how to write GenericDataRepository to accomplish this goal.
this is my interface
public interface IGenericDataRepository<T> where T : class
{
IList<T> Get(Func<T, bool> filter, int page, int pageSize, string[] includePaths = null, params SortExpression<T>[] sortExpressions);
}
}
Upvotes: 0
Views: 2554
Reputation: 7472
Use the dependency inversion principle. Inject a DbContext factory in your class constructor. Create and dispose of the context using the factory instead of accessing the context directly.
Here is a rough sample:
public class GenericDataRepository<T> : IGenericDataRepository<T> where T : class
{
private readonly Func<DbContext> _contextFactory;
public GenericDataRepository(Func<DbContext> contextFactory)
{
_contextFactory = contextFactory;
}
public virtual IList<T> Get(Func<T, bool> filter, int page, int pageSize, string[] includePaths = null, params SortExpression<T>[] sortExpressions)
{
List<T> list;
using (var context = contextFactory())
{
//...
}
}
}
Assuming that the layer which is using the generic data repository has access to Dbcontext, they can now instantiate the repository in the following manner:
var repository = new GenericDataRepository<SomeType>(DbContextfactory);
public void DbcontextFactory()
{
return new _DbContext();
}
Upvotes: 1