Reputation: 9332
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.
Upvotes: 0
Views: 1765
Reputation: 2047
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 IUnitOfWork
to a EntityFrameworkDbContext
type 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 expect IUnitOfWork
(that has 1 method), but under the hood your code works only, if you pass an EntityFrameworkDbContext
? And I would guess code would fail, if the parameter is not an actual EntityFrameworkDbContext
?
If you use that actual EF datacontext, you can pass in an actual EntityFrameworkDbContext
instance to all callers using Ninject like this:
//this makes sure all contexts use the same DbContext
ninjectKernel.Bind<EntityFrameworkDbContext>().To<EntityFrameworkDbContext>().InRequestScope();
Upvotes: 1