Asp.NET 应用程序中的单例

本文关键字:单例 应用程序 NET Asp | 更新日期: 2023-09-27 18:34:34

在我的应用程序中,我为每个调用创建一个数据库上下文,并且依赖项通过Ninject注入它。

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

但是,由于对象是单例对象,因此每个请求都会覆盖上下文,这对我不起作用(我不希望多个请求共享一个上下文(。

执行此操作的最佳方法是什么(如何最好仅在请求范围内使用单个上下文(?

Asp.NET 应用程序中的单例

您描述的不是单一实例,而是请求范围的对象。 ASP.NET MVC 对依赖项注入有很强的支持,你应该允许 DI 绑定来确定上下文的来源,而不是自己实例化它。Ninject 有绑定语法来支持这一点。我认为是这样:

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

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

依靠依赖关系注入来构造上下文的优点是,如果要更改详细信息(如禁用上下文上的更改跟踪(,只需更改 DI 绑定即可使用自定义方法或工厂,其余代码根本不需要更改。

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

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

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

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