I have been looking through Code Review on the subject of Unit of Work and Repository patterns and realised that my implementation appears to provide very similar functionality but in reverse class order/hierarchy. (Couldn't think of a better way to describe it sorry)
This is one of the questions I feel mine is similar to but in reverse.
I have added my code below. I would appreciate any feedback on my implementation you can offer regarding correctness, efficiency, and any suggestions.
UnitOfWork.cs - UnitOfWork + IUnitOfWork
public class UnitOfWork : IUnitOfWork
{
PropertyInfoEntities _context = null;
public IXXXXXRepository XXXXXRepository { get; set; }
public IPersonRepository PersonRepository { get; set; }
public IPersonLoginRepository PersonLoginRepository { get; set; }
public IPropertyApplicationRepository PropertyApplicationRepository { get; set; }
public ISaleTypeRepository SaleTypeRepository { get; set; }
public IStatusRepository StatusRepository { get; set; }
public ITownRepository TownRepository { get; set; }
public ITypeRepository TypeRepository { get; set; }
public UnitOfWork() : this(new PropertyInfoEntities()) { }
public UnitOfWork(PropertyInfoEntities context)
{
_context = context;
InitRepositories();
}
private void InitRepositories()
{
XXXXXRepository = new XXXXXRepository(_context);
PersonRepository = new PersonRepository(_context);
PersonLoginRepository = new PersonLoginRepository(_context);
PropertyApplicationRepository = new PropertyApplicationRepository(_context);
SaleTypeRepository = new SaleTypeRepository(_context);
StatusRepository = new StatusRepository(_context);
TownRepository = new TownRepository(_context);
TypeRepository = new TypeRepository(_context);
}
public void Save()
{
_context.SaveChanges();
}
#region IDisposable Members
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing == true)
{
_context = null;
}
}
~UnitOfWork()
{
Dispose(false);
}
#endregion
}
public interface IUnitOfWork : IDisposable
{
IXXXXXRepository XXXXXRepository { get; set; }
IPersonRepository PersonRepository { get; set; }
IPersonLoginRepository PersonLoginRepository { get; set; }
IPropertyApplicationRepository PropertyApplicationRepository { get; set; }
ISaleTypeRepository SaleTypeRepository { get; set; }
IStatusRepository StatusRepository { get; set; }
ITownRepository TownRepository { get; set; }
ITypeRepository TypeRepository { get; set; }
void Save();
}
XXXXXRepository.cs - XXXXXRepository + IXXXXXRepository
public class XXXXXRepository : IXXXXXRepository
{
PropertyInfoEntities _context = null;
public XXXXXRepository() : this(new PropertyInfoEntities()) { }
public XXXXXRepository(PropertyInfoEntities context)
{
_context = context;
}
public IQueryable<XXXXX> All
{
get { return _context.XXXXXs; }
}
public IQueryable<XXXXX> AllIncluding(params Expression<Func<XXXXX, object>>[] includeProperties)
{
IQueryable<XXXXX> query = _context.XXXXXs;
foreach (var includeProperty in includeProperties)
{
query = query.Include(includeProperty);
}
return query;
}
public XXXXX Find(int id)
{
return _context.XXXXXs.Find(id);
}
public XXXXX FindNT(int id)
{
return _context.XXXXXs.AsNoTracking().Single(f => f.ID == id);
}
public void InsertOrUpdate(XXXXX XXXXX)
{
if (XXXXX.ID == default(int))
{
// New entity
_context.XXXXXs.Add(XXXXX);
}
else
{
// Existing entity
_context.Entry(XXXXX).State = System.Data.Entity.EntityState.Modified;
}
}
public void Delete(int id)
{
var XXXXX = _context.XXXXXs.Find(id);
_context.XXXXXs.Remove(XXXXX);
}
public void Save()
{
_context.SaveChanges();
}
public void Dispose()
{
_context.Dispose();
}
}
public interface IXXXXXRepository : IDisposable
{
IQueryable<XXXXX> All { get; }
IQueryable<XXXXX> AllIncluding(params Expression<Func<XXXXX, object>>[] includeProperties);
XXXXX Find(int id);
XXXXX FindNT(int id);
void InsertOrUpdate(XXXXX XXXXX);
void Delete(int id);
void Save();
}
Providing my implementation was not incorrect, I was planning to change the UoW Repository Properties to self instantiating fields to increase efficiency, and load into a controller using a BaseController. However reading through some other Code Review questions has made my implementation feel wrong.
EDIT (4 years on): Looking back, my implementation was horrendous; mainly because of the InitRepositories() method that was called by the UoW constructor. This meant that for every instantiation of the UoW, it would instantiate each and every repository, regardless of whether they may be used or not. Aside from this the implementation isn't too bad, though it does work in reverse order to most others. If you want to hold the repositories explicitly within the UoW, you should implement them as (forgive my terminology) lazily self-instantiating properties, like here. Nowadays my preference is to use URF.NET and customise it as required.