I\'m currently using Entity Framework with a Generic Repository and Unit Of Work Pattern. My Model is similar to the one described in this article
I\'ve used Generic Rep
The approach of this article is really something that can be become a pain, because you already have a generic repository and a generic IUnitOfWork in EF and creating the specific repository for each type just removes the benefit of the generic!
I am posting here a sample of how i have a generic Repository and my IUnitOfWork, with this you can have a very nice repository!
public interface IUnitOfWork : IDisposable
{
void Save();
void Save(SaveOptions saveOptions);
}
public interface IRepository : IDisposable where TEntity : class
{
IUnitOfWork Session { get; }
IList GetAll();
IList GetAll(Expression> predicate);
bool Add(TEntity entity);
bool Delete(TEntity entity);
bool Update(TEntity entity);
bool IsValid(TEntity entity);
}
And the implementation something like:
public class Repository : Component, IRepository
{
protected DbContext session;
public virtual IUnitOfWork Session
{
get
{
if (session == null)
throw new InvalidOperationException("A session IUnitOfWork do repositório não está instanciada.");
return (session as IUnitOfWork);
}
}
public virtual DbContext Context
{
get
{
return session;
}
}
public Repository(IUnitOfWork instance)
{
SetSession(instance);
}
public IList GetAll() where TEntity : class
{
return session.Set().ToList();
}
public IList GetAll(Expression> predicate) where TEntity : class
{
return session.Set().Where(predicate).ToList();
}
public bool Add(TEntity entity) where TEntity : class
{
if (!IsValid(entity))
return false;
try
{
session.Set(typeof(TEntity)).Add(entity);
return session.Entry(entity).GetValidationResult().IsValid;
}
catch (Exception ex)
{
if (ex.InnerException != null)
throw new Exception(ex.InnerException.Message, ex);
throw new Exception(ex.Message, ex);
}
}
public bool Delete(TEntity entity) where TEntity : class
{
if (!IsValid(entity))
return false;
try
{
session.Set(typeof(TEntity)).Remove(entity);
return session.Entry(entity).GetValidationResult().IsValid;
}
catch (Exception ex)
{
if (ex.InnerException != null)
throw new Exception(ex.InnerException.Message, ex);
throw new Exception(ex.Message, ex);
}
}
public bool Update(TEntity entity) where TEntity : class
{
if (!IsValid(entity))
return false;
try
{
session.Set(typeof(TEntity)).Attach(entity);
session.Entry(entity).State = EntityState.Modified;
return session.Entry(entity).GetValidationResult().IsValid;
}
catch (Exception ex)
{
if (ex.InnerException != null)
throw new Exception(ex.InnerException.Message, ex);
throw new Exception(ex.Message, ex);
}
}
public virtual bool IsValid(TEntity value) where TEntity : class
{
if (value == null)
throw new ArgumentNullException("A entidade não pode ser nula.");
return true;
}
public void SetSession(IUnitOfWork session)
{
SetUnitOfWork(session);
}
protected internal void SetUnitOfWork(IUnitOfWork session)
{
if (!(session is DbContext))
throw new ArgumentException("A instância IUnitOfWork deve um DbContext.");
SetDbContext(session as DbContext);
}
protected internal void SetDbContext(DbContext session)
{
if (session == null)
throw new ArgumentNullException("DbContext: instance");
if (!(session is IUnitOfWork))
throw new ArgumentException("A instância DbContext deve implementar a interface IUnitOfWork.");
this.session = session;
}
}