Controller injection with Unity under ASP.NET MVC 4

A lot of different manuals exist on the web explaining various portions of MVC unit testing, Entity Framework mocking and Inversion of Control (IoC) using Unity as dependency injection container. In this and hopefully future posts I’ll try to sew together the bits I found on various places.

Of course any sane person would want to test their data access and MVC controllers using a mockable repository. For starters, you just need to test your code so you are forced to write it in a maintainable manner and thought-out patterns, which causes you to see repetitive code and be able to abstract that into base classes or even a library, and second: you don’t want your test code to access the database. You do want to test whether stuff gets read from and written to the database adapter, or Entity Framework as is the case here, but as long as we can mock that database behind it, we can make sure to be only testing our code, which was the initial goal. You don’t need to test Entity Framework’s code (although you can)!

You’ll do have to test with Entity Framework though, because for example some expressions or inheritance structures may work well on in-memory structures, but not on a database. When the repository is properly abstracted, the mocked repository should be replacable with the real one, so you can run all existing tests using either or both repositories.

In order to inject an Entity Framework DbContext (or a mock thereof, or anything really) into an ASP.NET MVC controller’s constructor, some mechanism is is required. See, this controller:

public class ContactsController : Controller
    private IMyProjectContext _context;

    public ContactsController(IMyProjectContext context)
        _context = context;

    public ActionResult Index()
        // TODO: we need Data Access. A controller should not have to know about the repository its data comes from.
        var contacts = _context.Contacts;
        return View(contacts);

Throws this error upon use:

MissingMethodException: No parameterless constructor defined for this object.

Because MVC does not know what to pass into the constructor. Unity and Unity.Mvc4 to the resue:

PM> Install-Package Unity and PM> Install-Package Unity.Mvc4.

I usually delete the files those packages generate, since they don’t fit my practices. When I read “Bootstrapper.Initialise()” it makes me think, which I try to do as less as possible. I want to read this, which makes sense and not me think:

protected void Application_Start()

Because in two weeks I will have forgotten what this “Bootstrapper” was, and two weeks after that I’ll have forgotten what “Unity” is (because once you set it up, you hardly ever go back ;-)). Code has to be explicit, you know, to be readable by others or yourself in a few months. For this code to work I create the file UnityConfiguration.cs in the App_Start folder of my MVC application, containing:

using System.Web.Mvc;
using Microsoft.Practices.Unity;
using CodeCaster.MVC.Unity;
using CodeCaster.MyProject.Data.Context;

namespace CodeCaster.MyProject.Web.App_Start
    public class UnityConfiguration
        public static void ConfigureIoCContainer()
            IUnityContainer container = new UnityContainer();            

            DependencyResolver.SetResolver(new UnityDependencyResolver(container));


        private static void RegisterTypes(IUnityContainer container)
            container.RegisterType<IMyProjectContext, MyProjectContext>(new TransientLifetimeManager());

That’s all there is to it! Now Unity.Mvc4’s UnityDependencyResolver captures MVC’s controller creation and creates a (currently parameterless ;-)) MyProjectContext that gets passed into the controller constructor.

Now in your testproject, you can instantiate your controller with a mocked repository as constructor parameter so you don’t have to test on the real database. More on this in the next blog!

This entry was posted in Tech and tagged , , , , , . Bookmark the permalink.

One Response to Controller injection with Unity under ASP.NET MVC 4

Leave a Reply