Asp.net mvc 我应该如何在web应用程序中定义Entity Framework DbContext的依赖项注入范围?(InstancePerHttpRequest vs SingleInstance)

Asp.net mvc 我应该如何在web应用程序中定义Entity Framework DbContext的依赖项注入范围?(InstancePerHttpRequest vs SingleInstance),asp.net-mvc,model-view-controller,autofac,dbcontext,single-instance,Asp.net Mvc,Model View Controller,Autofac,Dbcontext,Single Instance,我已经读到DbContext对象应该创建为InstancePerHttpRequest,而不是SingleInstance,因为它的线程不安全性,并且它可能会在请求之间消耗太多资源,这很有意义。 但我使用的是使用DbContext实例的存储库对象。我应该让它们成为InstancePerHttpRequest还是让它们成为SingleInstance并使用DependencyResolver来获取当前的DbContext 对于Autofac(或任何其他DI)、DbContext、存储库和基于服务的

我已经读到DbContext对象应该创建为InstancePerHttpRequest,而不是SingleInstance,因为它的线程不安全性,并且它可能会在请求之间消耗太多资源,这很有意义。 但我使用的是使用DbContext实例的存储库对象。我应该让它们成为InstancePerHttpRequest还是让它们成为SingleInstance并使用DependencyResolver来获取当前的DbContext

对于Autofac(或任何其他DI)、DbContext、存储库和基于服务的Web应用程序,最好的对象创建设计是什么


另一个问题是,为每个web请求的每个存储库或服务创建不同的DbContext对象(比如请求中的10-15个)的成本有多高?

DbContext的实例化成本非常低,因此我不必太担心获取新对象所需的时间


围绕DbContext进行范围界定的问题与其说是线程安全,不如说是查询隔离。因为任何人都可以调用save changes并将整个对象图提交到数据库,所以您希望确保只在具有特定更改的上下文中调用它

关于DbContext,需要了解的另一个关键问题是,跟踪的项目越多,性能就会下降。这意味着如果您将其绑定到singleton中,可能会导致一些非常严重的性能问题。(有很多方法可以解决这个问题,但如果你能注意到这一点,那就太好了,请看我在这篇上的文章)

我个人对web应用的偏好是将您的上下文和存储库绑定到HttpRequest的范围内。这意味着只有您当前的请求线程才能保存更改,并且还限制了您可能跟踪的项目数量


很抱歉,我的一些术语可能与autofac不匹配,因为我自己也是一个ninject人:)

DbContext实例化成本很低,所以我会将其设计为每个服务都有自己的实例。每个请求10-15就可以了,除非遇到问题,否则可以追溯到实例化的DBContext的数量。对我来说,其他任何东西都像是未成熟优化


我试图保持不可知论,因为我主要使用StructureMap。

DbContext是您的工作单元,因此不适合单实例范围。就这样对待它。有时,请求直接映射到UoW,但不一定总是这样。在将其应用于请求之前,请考虑这一点。 相关的可能重复:“任何人都可以调用保存更改并提交整个对象图”。这是线程安全问题,不是吗?当你共享一个
DbContext
accross-threads/requests时,你将陷入严重的困境。@Steven是的,这绝对适用于线程,但是我建议它甚至比线程问题更广泛。风险在于,即使在单线程应用程序中,如果您要查询某些数据并处理这些数据(无意保留这些更改),然后重用上下文执行更新,那么对附加对象的更新和以前的更改都将提交。这是建议将DbContext的范围保持在尽可能小的范围内(即仅限于您的工作单元)的原因之一。@Steven此外,长期使用DbContext的性能问题使其非常不切实际(没有手动管理跟踪图)