I would like you to review the solution I came up with to the following scenario:
In attempting to model a generic Repository object (that receives a generic type parameter) to interface with my data store, I created an abstract RepositoryBase class, that receives a DbContext parameter in the constructor, and implements a CRUD interface I called ICrud (providing create, read, update and delete methods).
Any repository in this application would then inherit from RepositoryBase and it would begin with all the CRUD methods ready for use.
I was asked not to do this, however, because not every entity the repository is intended to deal with should expose all CRUD methods. For example, the repository object that will handle DAL operations with object Message should expose only Read and Update methods (requirement imposition), whereas the BusinessCard repository is supposed to expose Create, Delete and Read.
What I ended up doing in the end was to create a helper class, named DALHelper, that implements ICrud. I then added a static class I called Infra, which has a method that returns an instance of a DALHelper.
Is this the optimal solution? Is there a better way to approach this?
RepositoryBase:
public abstract class RepositoryBase<T> where T : class
{
protected DbContext _dbContext;
private DbSet<T> _Entity { get { return _dbContext.Set<T>(); } }
public RepositoryBase()
{
_dbContext = new MilgamFormsContext();
}
public RepositoryBase(MilgamFormsContext dbContext)
{
_dbContext = dbContext;
}
}
ICrud:
public interface ICrud<T> where T : class, new()
{
List<T> Read();
List<T> Read(Predicate<T> predicate);
Int32 Create(T newEntity);
//Int32 Create(Predicate<T> predicate);
Int32 Update(T newEntityValues);
Int32 Update(Predicate<T> predicate, T newEntityValues);
Int32 Delete(T entity);
Int32 Delete(Predicate<T> predicate);
}
DALHelper:
public class DALHelper<T> : ICrud<T> where T : new()
{
DbContext _dbContext;
DbSet<T> _Entity { get { return _dbContext.Set<T>(); } }
public DALHelper(DbContext dbContext)
{
_dbContext = dbContext;
}
public List<T> Read()
{
List<T> messages = new List<T>();
try
{
messages = _Entity.ToList();
}
catch (Exception ex)
{
throw ex;
}
return messages;
}
public List<T> Read(Predicate<T> predicate)
{
List<T> filteredMessages = new List<T>();
try
{
filteredMessages = _Entity.Where((entity) => predicate(entity)).ToList();
}
catch (Exception ex)
{
throw ex;
}
return filteredMessages;
}
public int Create(T newEntity)
{
Int32 changedRows = 0;
try
{
if (newEntity != null)
{
_Entity.Add(newEntity);
changedRows = _dbContext.SaveChanges();
}
}
catch (Exception ex)
{
throw ex;
}
return changedRows;
}
public int Update(T rowToBeChanged)
{
Int32 changedRow = 0;
try
{
T rowCurrentState = _Entity.Find(rowToBeChanged.Id);
rowCurrentState = rowToBeChanged;
changedRow = _dbContext.SaveChanges();
}
catch (Exception ex)
{
throw;
}
return changedRow;
}
public Int32 Update(Predicate<T> predicate, T newEntityValues)
{
Int32 changedRows = 0;
List<T> changingRows = new List<T>();
try
{
changingRows = _Entity.Where((entity) => predicate(entity)).ToList();
for (Int32 i = 0; i < changingRows.Count; i++)
{
changingRows[i] = newEntityValues;
}
changedRows = _dbContext.SaveChanges();
}
catch (Exception ex)
{
throw;
}
return changedRows;
}
public Int32 Delete(T entity)
{
Int32 deletedRows = 0;
try
{
T removedEntity = _Entity.Remove(entity);
deletedRows = _dbContext.SaveChanges();
}
catch (Exception ex)
{
throw;
}
return deletedRows;
}
public Int32 Delete(Predicate<T> predicate)
{
Int32 deletedRows = 0;
List<T> rowsToDelete = new List<T>();
try
{
rowsToDelete = _Entity.Where(entityRow => predicate(entityRow)).ToList();
foreach (T entityRow in rowsToDelete)
{
_Entity.Remove(entityRow);
}
deletedRows = _dbContext.SaveChanges();
}
catch (Exception ex)
{
throw;
}
return deletedRows;
}
}
This is how a given Repository would look like:
public class MessageRepository : RepositoryBase<Message>
{
private DALHelper<Message> _dalHelper;
public MessageRepository()
{
_dalHelper = I.Infra.GetDALHelper<Message>(this._dbContext);
}
public Response<List<Message>> Get()
{
try
{
List<Message> messages = _dalHelper.Read();
return Response<List<Message>>.Success(messages);
}
catch (Exception ex)
{
return Response<List<Message>>.Failed(String.Format("Error in GetMessages. {0}", ex.Message));
}
}
public Response<Boolean> Create(Message message)
{
try
{
return _dalHelper.Create(message) == 1 ? Response<Boolean>.Success(true) : Response<Boolean>.Failed("Could not add message");
}
catch (Exception ex)
{
return Response<Boolean>.Failed(String.Format("Could not add message. {0}"), ex.Message);
}
}
}