Skip to main content

EntityFramework DbContext Lifetime Management with Ninject in ASP.NET MVC.

---
title: Managing EntityFramework DbContext Lifetime with Ninject in ASP.NET MVC
author: Dave Paquette
date: March 27, 2013
source: https://www.davepaquette.com/archive/2013/03/27/managing-entity-framework-dbcontext-lifetime-in-asp-net-mvc.aspx
notoc: false
---

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:

```csharp
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:

```csharp
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.

```csharp
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][1], but I have
also had good luck with [Autofac][2] and others.

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

```bash
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`:

```csharp
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
```

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

```csharp
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 behavior 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 for pointing this out!

[1]: http://www.Ninject.org
[2]: https://code.google.com/p/autofac/