Asp.NET应用程序中的Singleton

时间:2014-12-18 16:15:24

标签: c# asp.net entity-framework entity-framework-6

在我的应用程序中,我为每个调用创建一个dbcontext,依赖项通过Ninject注入它。

我一直在考虑创建一个单例类(ContextManager - BaseController将在每个请求上设置上下文),以使上下文可用,从而允许所有服务共享相同的上下文。这将使得例如禁用代理创建等变得容易,因为上下文仅从一个地方进行管理。

但是,当对象是单个对象时,每个请求都会覆盖上下文,这对我不起作用(我不希望多个请求共享一个上下文)。

最好的方法是什么(如何在请求范围内优先考虑单个上下文)?

2 个答案:

答案 0 :(得分:5)

您所描述的不是Singleton,而是Request-Scoped对象。 ASP.NET MVC强烈支持依赖注入,您应该允许DI绑定来确定上下文的来源,而不是自己实例化它。 Ninject有绑定语法来支持这一点。我认为:

Bind<DataContext>().ToSelf().InRequestScope();

只要您一致地使用良好的依赖注入模式,这应该导致相同的DataContext实例传递给您在同一请求中的每个依赖项。

依赖依赖注入来构建上下文的优势在于,如果要更改上下文中禁用更改跟踪等详细信息,则只需更改DI绑定即可使用自定义方法或工厂,其余你的代码根本不需要改变。

答案 1 :(得分:3)

Singleton不是正确的方法,但这并不难实现,只需在控制器中实例化数据上下文并将其注入服务类,例如:

public class SomeController {

     private DataContext _context;
     private SomeService _service;

     public SomeController() {
          _context = ...InstantiateContext();
          _service = new SomeService(_context);
     }   
}

如果您希望对其进行单元测试,这也允许将上下文注入控制器相对简单。您还可以通过将其编码到控制器类的dispose方法中来相对简单地处理您的上下文(如上所述,基本控制器类可能很有用)。

单身人员带有一些持久状态 - 这对单元测试来说是一种诅咒,最终会给你的代码带来困难。