【问题标题】:What is the correct way to manage dependency injection for Entity Framework ObjectContext in ASP.NET MVC controllers?在 ASP.NET MVC 控制器中管理实体框架 ObjectContext 依赖注入的正确方法是什么?
【发布时间】:2012-04-26 22:57:42
【问题描述】:

在我的 MVC 控制器中,我使用的是 IoC 容器 (Ninject),但不确定如何最好地使用实体框架 ObjectContext。

目前,我正在做类似的事情:

using(var context = new MyObjectContext())
{
     var stuff = m_repository.GetStuff(context);
}

从尽可能短的时间内保持数据库连接打开的角度来看,这是最好的管理方式。

如果我基于每个请求通过 Ninject 创建 ObjectContext,这显然会使数据库连接打开太久。

上面的代码也会变成...

var stuff = m_repository.GetStuff(m_myObjectContext);

(我什么时候处理上下文...?)

我应该为 ObjectContext 创建一个工厂并通过 DI 传递它吗?这会放松耦合,但是如果没有简单的方法来维护 ObjectContext 的接口(据我所知),这真的有助于可测试性吗?。

有没有更好的方法?谢谢

【问题讨论】:

    标签: entity-framework dependency-injection inversion-of-control


    【解决方案1】:

    从保持 数据库连接打开时间尽可能短。

    如果我要根据每个请求通过 Ninject 创建 ObjectContext 显然,这显然会使数据库连接打开的时间过长。

    Entity Framework 将在执行每个查询后立即关闭连接(从外部提供打开连接时除外),因此您对执行此类操作的论点不成立。

    过去我曾经通过业务逻辑(准确地说是我的command handlers)控制上下文(创建、提交和处置),但缺点是您需要将此上下文传递给所有其他方法和所有依赖项。当应用程序逻辑变得更复杂时,这会导致代码的可读性和可维护性降低。

    出于这个原因,我转向了一个模型,在该模型中,工作单元(您的 MyObjectContext)在业务逻辑的控制之外创建、提交和处置。这允许您将工作单元注入所有依赖项并为所有对象重用相同的工作单元。缺点是这会使您的 DI 配置更加困难。您需要确保的一些事项:

    1. 必须根据 Web 请求或在一定范围内创建工作单元。
    2. 工作单元必须在请求或作用域的末尾进行处理(尽管在未处理DbContext 时可能不是问题,因为底部连接已关闭且DbContext 未实现终结器)。
    3. 您需要明确提交工作单元,但不能在 Web 请求结束时执行此操作,因为此时您不知道提交是否安全(因为您不想当您的业务逻辑抛出异常时提交,但在请求结束时无法正确检测这是否真的发生)。

    我可以给您的一个提示是围绕command handlers 对系统中的业务逻辑进行建模,因为这允许您定义一个处理事务行为的单个装饰器(提交工作单元,甚至可能在一个数据库事务)在一个点。这个装饰器可以包裹在系统中的每个处理程序周围。

    我必须承认,我不知道如何使用 Ninject 注册泛型类型和泛型装饰器,但是当您在 Stackoverflow 上提问时,您可能会很快得到答案。

    【讨论】:

      猜你喜欢
      • 2010-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-30
      • 2018-04-16
      相关资源
      最近更新 更多