使用MVC应用程序时,管理Entity Framework上下文的最佳方法是什么?
我正在使用存储库/服务模式。
修改
在查看其中一些问题之后:stackoverflow.com/users/587920/sam-striano,我之前更加困惑。有人说使用每个存储库的上下文,但是如果我想在一个控制器方法中使用多个存储库呢?
为了遵循良好的分离设计,如何在MVC应用程序中使用UnitOfWork而不依赖于EF?我希望能够使用模拟上下文对我的控制器,模型,服务等进行单元测试吗?
答案 0 :(得分:6)
使用依赖注入器/控制反转框架,如:
使用IoC容器,您可以告诉它如何管理单个数据上下文(最常见的是,每个请求)。当您为每个请求设置数据上下文时,容器将自动神奇地为每个请求提供需要数据上下文相同数据上下文的任何类。
这是关于设置Ninject的good article。
假设您使用的是通用存储库,那么您的代码最终会看起来像什么:
Ninject模块:
public class NinjectRegistrationModule : NinjectModule
{
public override void Load()
{
Bind<MyDataContext>().ToSelf().InRequestScope();
Bind(typeof(RepositoryImplementation<>)).ToSelf().InRequestScope();
}
}
通用存储库:
public RepositoryImplementation<T> : IRepository<T> where T : class
{
MyDataContext _dataContext;
public RepositoryImplementation<T>(MyDataContext dataContext)
{
_dataContext = dataContext;
}
// bunch of methods that utilize _dataContext
}
服务类:
public class MyServiceClass
{
IRepository<SomeEntity> _someEntityRepository;
public MyServiceClass(IRepository<SomeEntity> someEntityRepository)
{
_someEntityRepository = someEntityRepository;
}
// do stuff with _someEntityRepository = someEntityRepository;
}
<强>控制器:强>
public class MyController
{
MyServiceClass _myServiceClass;
public MyController(MyServiceClass myServiceClass)
{
// Ninject will auto-magically give us a myServiceClass
// which will Ninject will inject a repository into MyServiceClass's constructor
_myServiceClass = myServiceClass;
}
public ActionResult MyAction()
{
// use _myServiceClass to do stuff
return View();
}
}
答案 1 :(得分:0)
如果您的功能很简单,那么您应该在每个存储库中创建一个新的ObjectContext。实例化它们很便宜。
如果这会产生冲突,您可以使用评论中建议的工作单元模式。
我建议您在将ObjectContext或DataContext与DI容器集成时要非常谨慎。许多人默认情况下不会在其生命周期中使用适当的范围。