我有一个MVC3解决方案,我有2个存储库& 2个服务层。我也有单独的每一层:控制器< - >服务< - >存储库
以前,在我的每个存储库中,我都有一个单独的数据上下文。我是说我在每个存储库中创建了一个新的对象实例。我知道这不是好方法。
所以我重构了我的解决方案,以便在我的存储库之间共享我的数据上下文。以下是我的解决方案的骨架。我想要你的意见。
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();
}
nInject绑定
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>();
控制器
public class AdminController : Controller
{
private IMainService m_MainService;
private IAdminService m_AdminService;
public AdminController(IMainService mainService, IAdminService adminService)
{
m_MainService = mainService;
m_AdminService = adminService;
}
...
}
服务
public class MainService : IMainService
{
private IMainRepository m_Repository;
public MainService(IMainRepository repository)
{
m_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;
}
...
}
正如您所见,我实施了工作单元模式,但我不知道这是否是一种好方法。
感谢。
答案 0 :(得分:1)
使用与MVC3和Linq2SQL类似的方法,所以我想这也适用于Entity Framework。只要确保向其他开发人员说明这一事实,默认情况下,如果没有另外说明,同一请求中的所有查询都使用相同的EF DbContext。
一句话:您实际上已将IUnitOfWork
转换为存储库中的EntityFrameworkDbContext
类型,我猜您不能将其替换为其他实现。发布给调用者是一个好主意,你期望IUnitOfWork
(有1种方法),但是如果你传递EntityFrameworkDbContext
,你的代码只会起作用吗?如果参数不是实际的EntityFrameworkDbContext
?
如果您使用实际的EF datacontext,您可以使用Ninject将实际EntityFrameworkDbContext
实例传递给所有呼叫者,如下所示:
//this makes sure all contexts use the same DbContext
ninjectKernel.Bind<EntityFrameworkDbContext>().To<EntityFrameworkDbContext>().InRequestScope();