JensOlsen112
JensOlsen112

Reputation: 1299

Singleton in Asp.NET application

In my app, I create a dbcontext for every call and dependency inject it through 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. 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)?

Upvotes: 2

Views: 615

Answers (2)

StriplingWarrior
StriplingWarrior

Reputation: 156524

What you're describing is not a Singleton, but a Request-Scoped object. 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. Ninject has binding syntax to support this. 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.

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.

Upvotes: 5

Paddy
Paddy

Reputation: 33857

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, e.g.:

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).

A singleton carries some persistent state - this is anathema to unit testing and will ultimately give you difficulties in your code.

Upvotes: 3

Related Questions