I have an MVC3 solution where I have 2 repositories & 2 service layers. I also have separate every layer: controller <–> service <–> repository
Previously, in each of my repositories I had a separate data context. I mean I created a new object instance in each repository. I knew this is not the good way.
So I refactored my solution in order to share my data context between my repositories. Below is the skeleton of my solution. I would like your opinion.
public class EntityFrameworkDbContext: DbContext, IUnitOfWork
{
public DbSet<Project> Projects { get; set; }
public DbSet<Technology> Technologies { get; set; }
public void Save()
{
SaveChanges();
}
}
public interface IUnitOfWork
{
void Save();
}
The nInject bindings
ninjectKernel.Bind<IUnitOfWork>().To<EntityFrameworkDbContext>().InRequestScope();
ninjectKernel.Bind<IMainRepository>().To<MainRepository>();
ninjectKernel.Bind<IAdminRepository>().To<AdminRepository>();
ninjectKernel.Bind<IMainService>().To<MainService>();
ninjectKernel.Bind<IAdminService>().To<AdminService>();
Controller
public class AdminController : Controller
{
private IMainService m_MainService;
private IAdminService m_AdminService;
public AdminController(IMainService mainService, IAdminService adminService)
{
m_MainService = mainService;
m_AdminService = adminService;
}
...
}
Service
public class MainService : IMainService
{
private IMainRepository m_Repository;
public MainService(IMainRepository repository)
{
m_Repository = repository;
}
...
}
Repository
public class AdminRepository : IAdminRepository
{
private EntityFrameworkDbContext m_Context;
public AdminRepository(IUnitOfWork unitOfWork)
{
if (unitOfWork == null)
throw new ArgumentNullException("unitOfWork");
m_Context = unitOfWork as EntityFrameworkDbContext;
}
...
}
As you can see I implement the Unit of Work pattern but I don’t know if this is a good approach.
Thanks.
Used a similar approach with MVC3 and Linq2SQL, so I guess this should work for Entity Framework too. Just make sure that you tell the fact to other developers, that by default all queries in the same request use the same EF DbContext if not told otherwise.
One remark: You are effectively casting your
IUnitOfWorkto aEntityFrameworkDbContexttype in your Repository, and I guess you couldn’t just replace it with another implementation. Is it a good idea to publish to the callers, that you expectIUnitOfWork(that has 1 method), but under the hood your code works only, if you pass anEntityFrameworkDbContext? And I would guess code would fail, if the parameter is not an actualEntityFrameworkDbContext?If you use that actual EF datacontext, you can pass in an actual
EntityFrameworkDbContextinstance to all callers using Ninject like this: