Getting Umbraco and Unity working together

Using Unity for dependency injection can make your code easier to maintain and test, as a bonus it is fairly straight forward to setup in an Mvc project. I already had a lot of custom controllers and code in my Umbraco projects, so I wanted to get Unity working with Umbraco as my code base grew.

Adding Unity to the front end controllers is the easy part, simply install the nuget packages for Unity and Mvc in your web project.

Install-Package Unity.Mvc

This works for the standard controllers even with the Umbraco controllers on the front end, all that is required is to ensure dependencies are registered with unity and the constructors advertise the fact, for example:

public class ContentController : RenderMvcController
{
    private IContentService _contentService;

    public ContentController(IContentService contentService) 
    {
        this._contentService = contentService;

        public ActionResult Content()
        {
            var model = this._contentService.GetModel();
            return View(model);
        }
    }
}

Now the ContentController requires an instance that implements IContentService which Unity will handle whenever the system needs to create an instance of the Controller. In order to do that Unity needs to know what implementation of IContentService to use. This is achieved by registering the type in the Unity Config: 

public static void RegisterTypes(IUnityContainer container)
{
    container.RegisterType<IContentService, ContentService>();
}

I also have some Api controllers which unfortunately do not work as expected with the unity mvc package, a few posts suggest various workarounds and custom implementations but luckily Microsoft have addressed the need with an additional nuget package:

Install-Package Unity.AspNet.WebApi

At this point the front end looks good but if you now go into the Umbraco back office the following error will appear when trying to edit a page:

The current type, Umbraco.Core.Models.IPublishedContent, is an interface and cannot be constructed. Are you missing a type mapping?

Reading the Umbraco Documentation for IoC containers and most of the examples on the internet all use Autofac, and although the principle is the same I thought it might help someone to give a working example with Unity. The solution is to specifically trigger the container initialization within the Umbraco ApplicationStarted event:

protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
    var container = UnityConfig.GetConfiguredContainer();

    container.RegisterType<UmbracoContext>(new ContainerControlledLifetimeManager(), new InjectionFactory(c => UmbracoContext.Current));

    GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);

    container.BuildUp(typeof(ApplicationEvents), this);

    base.ApplicationStarted(umbracoApplication, applicationContext);
}

The not so obvious part found thanks to this thread, is to make sure that the UmbracoContext dependency is registered too; note the ContainerControlledLifetimeManager to give you a singleton instance behaviour. Now the back office should work as expected. This was tested with Umbraco 7.4.2 and Unity 4.0.1.