简体   繁体   English

Asp.NET应用程序中的Singleton

[英]Singleton in Asp.NET application

In my app, I create a dbcontext for every call and dependency inject it through Ninject. 在我的应用程序中,我为每个调用创建一个dbcontext,依赖项通过Ninject注入它。

I've been thinking of creating a singleton class (ContextManager - BaseController would set the context on every request) to make the context available from everywhere, thus allowing all the services to share the same context. 我一直在考虑创建一个单例类(ContextManager - BaseController将在每个请求上设置上下文),以使上下文可用,从而允许所有服务共享相同的上下文。 This would furthermore make it easy to, for example, disable proxy creating etc. seeing as the context is managed from one place only. 这将使得例如禁用代理创建等变得容易,因为仅从一个地方管理上下文。

However, seeing as the object is a singleton object the context would be overwritten per each request which won't work for me (I don't want multiple requests sharing a single context). 但是,当对象是单个对象时,每个请求都会覆盖上下文,这对我来说不起作用(我不希望多个请求共享一个上下文)。

What would be the best way to do this (how to preferably a single context ONLY in request scope)? 最好的方法是什么(如何在请求范围内优选单个上下文)?

What you're describing is not a Singleton, but a Request-Scoped object. 你所描述的不是Singleton,而是Request-Scoped对象。 ASP.NET MVC has strong support for dependency injection, and you should allow your DI bindings to determine where the context comes from, rather than instantiating it yourself. ASP.NET MVC强烈支持依赖注入,您应该允许DI绑定来确定上下文的来源,而不是自己实例化它。 Ninject has binding syntax to support this. Ninject有绑定语法来支持这一点。 I think it goes: 我认为它是:

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

As long as you are using good Dependency-Injection patterns consistently, this should cause the same DataContext instance to be passed to every dependency you have within the same request. 只要您一致地使用良好的依赖注入模式,这应该导致相同的DataContext实例传递给您在同一请求中的每个依赖项。

The advantage to relying on Dependency Injection for construction of your context is that if you want to change details like disabling change tracking on the context, you can simply change your DI binding to use a custom method or factory, and the rest of your code doesn't have to change at all. 依赖依赖注入构建上下文的优势在于,如果要更改上下文中禁用更改跟踪等详细信息,只需更改DI绑定即可使用自定义方法或工厂,其余代码也可以根本不需要改变。

Singleton is not the right approach here, but this is not too hard to implement, by simply instantiating your data context in your controller and injecting it into your service classes, eg: Singleton不是正确的方法,但通过简单地在控制器中实例化数据上下文并将其注入服务类,这并不难实现,例如:

public class SomeController {

     private DataContext _context;
     private SomeService _service;

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

This also allows makes it relatively simple to inject your context into your controller if you wish to unit test that. 如果您希望对其进行单元测试,这也允许将上下文注入控制器相对简单。 You can also relatively simply dispose of your context by coding this into the dispose method of the controller class (as noted above, a base controller class may be useful). 您还可以通过将其编码到控制器类的dispose方法中来相对简单地处理您的上下文(如上所述,基本控制器类可能很有用)。

A singleton carries some persistent state - this is anathema to unit testing and will ultimately give you difficulties in your code. 单例带有一些持久状态 - 这是单元测试的诅咒,最终会给你的代码带来困难。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM