Managing Entity Framework DbContext Lifetime in ASP.NET MVC

Managing the lifetime of a DbContext instance in your application is extremely important. A DbContext makes use of important resources like database connections that need to be released. If you do not properly dispose of a DbContext instance, the underlying database connections might never be released back to the connection pool. Anyone who has done any old school ADO.NET programming knows the madness that lies down that path.

In an ASP.NET MVC application, the DbContext instances are typically used inside a controller. For some background, controllers in MVC are created when as a web request comes in and they are disposed of when that request is completed. In ASP.NET MVC controllers, how can we ensure that our DbContext instance is disposed? (Spoiler Alert: You should use option 3)

Option 1) The Using Pattern

One option is to use the using pattern:

using (EmployeeContext context = new EmployeeContext())
{
return View(context.Employees.ToList());
}

The using pattern ensures that the EmployeeContext is disposed of at the end of the using block. It is basically shorthand for a try{… } finally{…} block where the context is disposed of in the finally. This pattern will ensure that the context is disposed, but it makes it difficult to share a context instance in different points of the application. You may find yourself creating more DbContext instances than you intended. It also adds some noise to your controller logic. While it is much cleaner than a try finally, it does still add noise.

Option 2) The Dispose Pattern

Another option is to implement the dispose pattern in your controller:

public class EmployeeController : Controller
{
private EmployeeContext _context;

public EmployeeController()
{

_context = new EmployeeContext();
}

public ActionResult Index()
{

return View(_context.Employees.ToList());
}

protected override void Dispose(bool disposing)
{

if (disposing)
{
_context.Dispose();
}
base.Dispose(disposing);
}
}

Again, this pattern ensures that the EmployeeCotenxt is disposed of when the controller is disposed of at the end of the request. Much like the using pattern, this option adds noise to your controller and it makes it difficult to share an instance of a context with different points in your application. It also relies on all developers on the team to properly implement the dispose pattern (one of the most misused patterns in the .NET world).

Option 3) Dependency Injection

This is the option that I choose. It is the cleanest possible option and it relieves the controller any responsibility for the lifetime of the DbContext instance. When you think about it, the controller requires an instance of a DbContext, but it really shouldn’t care about where it comes from or where it goes when it is done with it.

Start by adding a constructor that requires an instance of the DbContext.

public class EmployeeController : Controller
{
private EmployeeContext _context;

public EmployeeController(EmployeeContext context)
{

_context = context;
}

public ActionResult Index()
{

return View(context.Employees.ToList());
}
}

Since this is the only constructor, we know that the EmployeeController cannot be created without an instance of an EmployeeContext. It is no longer the responsibility of the controller to create the DbContext, which means it is no longer responsible for disposing of it either. Notice how simple the controller is now?

But wait! If the controller isn’t creating the context, then who is? This is an MVC application, who is creating the controllers? How can I be sure that the context is actually being disposed?

IoC Container to the Rescue!

Luckily,there are a number of dependency injection / IoC containers that have hooks in to MVC to help us with this. My favorites is NInject, but I have also had good luck with Autofac and others.

To get started with NInject, simply install the NInject.MVC3 nuget package.

Install-Package Ninject.MVC3

The nuget package will add a NInjectWebCommon.cs file to your application’s App_Start folder:

The important line in this file is the line that registers the OnePerRequestHttpModule:

DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));

You also need to add the following line to the CreateKernel method in NInjectWebCommon.cs

kernel.Bind<EmployeeContext>().ToSelf().InRequestScope();

With this configuration, NInject will recognize that your controller requires an instance of an EmployeeContext and do the following for you:

  • Create an instance of the EmployeeContext
  • Pass the instance in to the EmployeeController constructor
  • Dispose of the EmployeeContext at the end of the Http Request

Because we are using OnePerRequestHttpModule, the default behaviour is to create a new instance of the EmployeeContext for each Http request. That means different requests will never share an instance of a context. It will also ensure that no more than one EmployeeContext is created, even if the request ends up hitting 3 controllers that all require an EmployeeContext. In other words, the lifetime of the context is tied to the life of the request. This is a good thing and is definitely the recommended approach for Entity Framework. Use it!

Update 1: Updated to add the very important NInject configuration that ensures instances of the EmployeeContext are actually disposed properly. Thank you to my friend Robson (@TowTweets) for pointing this out!