Reputation: 1028
Consider the following generic Repository
interface and its implementation:
public interface IRepository<T>
{
IQueryable<T> FindAll(List<string> includes = null);
void Add(T entity);
void Update(T entity);
void Remove(T entity);
}
public class Repository<T> : IRepository<T> where T : class
{
protected DatabaseContext _dbContext { get; set; }
protected ILogger<Repository<T>> _logger { get; set; }
public Repository(DatabaseContext dbContext, ILogger<Repository<T>> logger)
{
_logger = logger;
_dbContext = dbContext;
}
public IQueryable<T> FindAll(List<string> includes = null)
{
try
{
IQueryable<T> items = _dbContext.Set<T>().AsNoTracking();
if (includes != null && includes.Any())
{
includes.Where(i => i != null).ToList().ForEach(i => { items = items.Include(i); });
}
return items;
}
catch (Exception e)
{
_logger.LogError(e, "{Repo} FindAll function error", typeof(Repository<T>));
return null;
}
}
public void Add(T entity)
{
try
{
_dbContext.Set<T>().Add(entity);
}
catch (Exception e)
{
_logger.LogError(e, "{Repo} Add function error", typeof(Repository<T>));
}
}
public void Update(T entity)
{
try
{
_dbContext.Set<T>().Update(entity);
}
catch (Exception e)
{
_logger.LogError(e, "{Repo} Update function error", typeof(Repository<T>));
}
}
public void Remove(T entity)
{
try
{
_dbContext.Set<T>().Remove(entity);
}
catch (Exception e)
{
_logger.LogError(e, "{Repo} Remove function error", typeof(Repository<T>));
}
}
}
In order to use this with a database entity like User
, I have two choices.
Either inherit UserRepository
implementation from generic Repository
:
public class UserRepository : Repository
{
public UserRepository(MyDbContext context) : base(context)
{
}
}
or create an instance of generic IRepository
interface in the UserRepository
implementation and use dependency injection:
public class UserRepository : IUserRepository
{
private readonly IRepository _repo;
public UserRepository(IRepository repo)
{
_repo = repo;
}
}
As per my limited experience with the Repository pattern in ASP.NET Core, I can use either of these and achieve the same results in a CRUD app that uses a database.
My question though is, which one should be used in which scenario?
Update:
I can still create and inject IUserRepository
by using the inheritance approach.
public partial interface IUserRepository : IRepository
{
}
public class UserRepository : Repository, IUserRepository
{
public UserRepository(MyDbContext context) : base(context)
{
}
}
Upvotes: 1
Views: 1008
Reputation: 26362
I can't help but notice that the IRepository
lost its genetic parameter.
The question to ask here is what you can gain by injecting the IRepository
inside your repositories. Are there going to be multiple implementations of the IRepository
in your applications lifetime?
Your abstraction here is the repository itself and that's what needs to be injected, not the IRepository
itself that I can't see any reason to have multiple or alternate implementations.
As it is also mentioned by Dai in the comments, you should not use it at all. The Generic repository has no point with EF and some people think there is no point at all.
Upvotes: 1