I am using EF/Repository/Unit of Work, but I am having a hard time understanding some details. Inside the UnitOfWork, I create a new EF DbContext (EmmaContext), but look at inside the repository, I cast it which I know is wrong, how do I get the context inside the repo correctly? Maybe I am totally on the wrong path?
Here is my UnitOfWork:
//Interface
public interface IUnitOfWork : IDisposable
{
void Commit();
}
//Implementation
public class UnitOfWork : IUnitOfWork
{
#region Fields/Properties
private bool isDisposed = false;
public EmmaContext Context { get; set; }
#endregion
#region Constructor(s)
public UnitOfWork()
{
this.Context = new EmmaContext();
}
#endregion
#region Methods
public void Commit()
{
this.Context.SaveChanges();
}
public void Dispose()
{
if (!isDisposed)
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
isDisposed = true;
if (disposing)
{
if (this.Context != null)
this.Context.Dispose();
}
}
#endregion
}
Here is the repository:
//Interface
public interface IRepository<TEntity> where TEntity : class
{
IQueryable<TEntity> Query();
void Add(TEntity entity);
void Attach(TEntity entity);
void Delete(TEntity entity);
void Save(TEntity entity);
}
//Implementation
public abstract class RepositoryBase<TEntity> : IRepository<TEntity> where TEntity : class
{
#region Fields/Properties
protected EmmaContext context;
protected DbSet<TEntity> dbSet;
#endregion
#region Constructor(s)
public RepositoryBase(IUnitOfWork unitOfWork)
{
this.context = ((UnitOfWork)unitOfWork).Context;
this.dbSet = context.Set<TEntity>();
}
#endregion
#region Methods
public void Add(TEntity entity)
{
dbSet.Add(entity);
}
public void Attach(TEntity entity)
{
dbSet.Attach(entity);
}
public void Delete(TEntity entity)
{
dbSet.Remove(entity);
}
public IQueryable<TEntity> Query()
{
return dbSet.AsQueryable();
}
public void Save(TEntity entity)
{
Attach(entity);
context.MarkModified(entity);
}
#endregion
}
Sam: I usually feel comfortable with a concrete Repository taking a concrete UnitOfWork in the ctor:
public RepositoryBase(UnitOfWork unitOfWork)
{
this.context = unitOfWork.Context;
this.dbSet = context.Set<TEntity>();
}
The repository and UoW typically work in concert and need to know a little bit about each other.
Of course the code consuming these classes only know about the interface definitions and not the concrete types.
This is the best article I've read.
In their example, they manage the repositories like this:
private SchoolContext context = new SchoolContext();
private GenericRepository<Department> departmentRepository;
private GenericRepository<Course> courseRepository;
public GenericRepository<Department> DepartmentRepository
{
get
{
if (this.departmentRepository == null)
{
this.departmentRepository = new GenericRepository<Department>(context);
}
return departmentRepository;
}
}
Your unit of work holds the context, and if it needs to reference a repository, it creates it if it has not been created, and passes in the context that it's holding.
The article also walks through how they converted a regular MVC controller implementation into using the unit of work pattern.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With