如何使用实体框架和Ninject处理依赖注入的MVC控制器中的范围问题

时间:2015-04-24 15:30:15

标签: asp.net-mvc dependency-injection ninject

基本上我有一组控制器将业务层对象注入其中,这些业务层对象将需要主要使用实体框架的数据访问层对象。

我和我的团队有点失落的领域是如何/何时创建这些注入的数据库上下文。我们主要担心的是,我们不希望每次请求进入时都会创建新的上下文,因为我们会执行相当多的ajax请求。以下是我们迄今为止的一些想法

  1. 瞬态范围
    我们得出的结论是,即使请求只是一个不需要实体上下文的ajax请求,这也会导致为控制器的每个请求创建新的上下文。另外,我们需要处理上下文。
  2. 家长范围
    这比第一个要好,因为ninject会处理上下文。但它仍然存在为每个请求新建一个实例的问题。
  3. 单身范围
    由于使用相同数据库上下文的大量连接的内存问题而不实用
  4. 请求范围
    我们认为这实际上会导致使用瞬态作用域的确切行为,因为MVC为每个请求创建了一个新的控制器
  5. 所有这些都是基于我们的假设,即MVC将为每个请求创建新的控制器(而不是在同一个用户向站点发出请求时保持它们),并且创建的实体框架对象将是一个内存问题

    我们的假设是否正确?如果是这样,我们有办法让每个用户基于实体框架上下文或我们的控制器的特定实例。

    编辑:

    我们想要避免的一个例子如下。根据我的理解,由于用户在ui中滚动,发出多个ajax调用的同一客户端将导致ScrollResults将导致生成新的控制器和IContext。 SomeAjaxMethod也会导致创建一个新的EF对象,即使它不会使用它。但是,如果新建的新EF对象对性能的影响可以忽略不计,那么我们可以接受它。

    //Context would be our entity framework object that would be injected
    public SomeController(IContext context )
    {
        _ctx = context;
    }
    //Ajax method that loads more data whenever the user scrolls to far
    public JsonResult ScrollResults(int group){
            this._ctx.stuff();
    }
    public JsonResult SomeAjaxMethod(int group){
          //Stuff that does not require the entity connection, but still causes 
          //a new controller and entity framework object to be created
    }
    

1 个答案:

答案 0 :(得分:2)

如果没有完全了解您如何设置AJAX交互,则很难具体回答。

我确信在某些特定情况下你可能需要偏离请求范围,但我还没有在我的日常工作中找到这个理由。

请求范围很好地映射到Web请求的流程。在我完成的任何工作中,为每个请求创建新的上下文都没有问题。你能在项目中提供一个不受欢迎的场景吗?或者只是您关注的绩效观点?

如果您考虑实体框架DbContext的生命周期,请求范围实际上非常适合Web项目。让我们假装您为网络用户A和用户B使用相同的上下文。如果用户A读取10个新闻项,则编辑1并保存。当用户B出现在产品上时会发生什么?上下文已包含10个新闻项(以及编辑过的1个)。

用户2在他们使用的上下文中与新闻项目有什么关系?这是低效的,因此Request Scope通过为每个请求发出新的上下文来解决此问题。您在每个Web请求之间都有自动隔离。