MVC 中带有 Ninject 的适当存储库生命周期范围
在 MVC 3 应用程序中将 Entity Framework 4 与 Ninject 结合使用时,存储库和 EF 上下文的适当生命周期范围是什么?
我一直在使用默认的 InTransientScope,但质疑它是否应该是 InRequestScope。
public class MyController: Controller
{
private readonly IMyRepo _repo;
public MyController(IMyRepo repo)
{
_repo = repo;
}
public ActionResult Index()
{
var results = _repo.GetStuff();
return View(results);
}
}
Ninject 模块:
public class MyServices : NinjectModule
{
public overrride void Load()
{
Bind<IMyRepo>.To<MyRepo>();
Bind<MyContext>.ToSelf();
}
}
MyRepo:
public class MyRepo: IMyRepo
{
private readonly MyContext _context;
public MyRepo(MyContext context)
{
_context = context;
}
public IEnumerable GetStuff()
{
return _context.Entity;//query stuff
}
}
What is the appropriate LifeCycle Scope for a repository and the EF context when using Entity Framework 4 with Ninject in an MVC 3 application?
I've been using the default of InTransientScope, but questioning whether it should be InRequestScope.
public class MyController: Controller
{
private readonly IMyRepo _repo;
public MyController(IMyRepo repo)
{
_repo = repo;
}
public ActionResult Index()
{
var results = _repo.GetStuff();
return View(results);
}
}
Ninject Module:
public class MyServices : NinjectModule
{
public overrride void Load()
{
Bind<IMyRepo>.To<MyRepo>();
Bind<MyContext>.ToSelf();
}
}
MyRepo:
public class MyRepo: IMyRepo
{
private readonly MyContext _context;
public MyRepo(MyContext context)
{
_context = context;
}
public IEnumerable GetStuff()
{
return _context.Entity;//query stuff
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您的存储库可以是瞬态范围,但是,我会将上下文绑定在请求范围中。这样,您的所有存储库实例将共享相同的上下文。通过这种方式,您可以获得 ORM 的缓存和事务优势。
当前它在代码中的工作方式是,每当您请求一个新上下文时,都会创建一个新上下文。因此,如果您的控制器首先使用存储库,然后调用另一个模块,该模块又使用存储库。每个存储库都将具有不同的上下文实例。因此,实际上您现在只是将 ORM 用作连接管理器和 SQL 生成器。
这也可能产生意想不到的后果。想象一下如下代码:
如果 DoStuff 方法最终再次调用
_repository.Get(id);
,您将拥有不同步的实体的 2 个不同副本。Your repository can be transient scope, however, I would bind the context in request scope. This way all of your repository instances will share the same context. This way you can reap the caching and transactional benefits of an ORM.
The way it works currently in your code is that a new context is created any time you request one. So if your controller first uses a repository and then calls another module that in turn uses a repository. Each of those repositories will have a different instance of the context. So in effect you are now using your ORM simply as a connection manager and SQL generator.
This can also have unintended consequences. Imagine a code like the following:
If the DoStuff method, eventually calls
_repository.Get<Entity>(id);
again, you will have 2 different copies of your entity that are out of sync.这取决于几个因素。
您关心交易吗?瞬态作用域并不适合您。
您是否关心交易,但认为每个网络请求一笔交易适合您?然后使用 Web 范围。
您是否同意将对象“缓存”在 EF 上下文中,并且如果您两次请求同一对象,则不希望完全刷新数据库? Web 范围有此副作用。
This depends on a couple of factors.
Do you care about transactions at all? It not that transient scope is ok for you.
Do you care about transactions but think one transaction per web request is ok for you? Then use web scoped.
Are you ok with objects being "cached" in EF's context and don't want a full database refresh if you request the same object twice? Web scope has this side effect.