Integrating The Unity.Mvc3 1.1 NuGet Package From Scratch
A new version of Unity.Mvc3 has been published that targets the recently released Unity 2.1. It is available as a NuGet Package (Unity.Mvc3) downloadable from within Visual Studio. You can also download the dll and the source code from codeplex. This article explains the changes in this release and goes on to explain how to do dependency injection in an MVC application using Unity.Mvc3.
Changes from 1.0
Following the release of a new version of Unity (2.1), I have updated the project to use this newer version. I have also changed the RegisterControllers extension method to be on IUnityContainer rather than the concrete UnityContainer type, which was a mistake that crept into the original release. The other changes are in the NuGet package itself. I have now added a dependency on the Unity NuGet package rather than relying on the consumer to install it either via NuGet or as part of Enterprise Library. I had initially held off on adding this dependency assuming that many developers would already have Unity installed as part of Enterprise Library, but I have been persuaded that the benefits outweigh the drawbacks. I have also added a simple bootstrapper class that creates the Unity container, registers the controllers and then creates and registers the DependencyResolver with MVC.
Getting started with Unity.Mvc3
These changes mean that you can now get up and running much more quickly than with the previous release. The rest of this article will show how to start from scratch, building an MVC3 application that uses the Unity.Mvc3 NuGet package to allow dependency injection in a series of simple scenarios.
First we create a new MVC3 application and select the Internet Application Template to add some simple controllers and views to the project.
Figure 1: The Visual Studio 2010 New Project Dialog
Figure 2: The Visual Studio 2010 New ASP.NET MVC3 Internet Application Template
The next thing to do is add the NuGet Unity.Mvc3 package to the project. Right-click on references and select Manage NuGet packages. Once the dialog appears, enter Unity.Mvc3 into the search box in the top right corner. After a few seconds, the results will be displayed in the centre panel. Select the Unity.Mvc3 package and click Install.
Figure 3: Manage NuGet Packages Context Menu Item
Figure 4: Manage NuGet Packages Dialog
The NuGet installer will add Unity and Unity.Mvc3 DLL's to the project references and also add a couple of files to the root of the application. Unity.Mvc3.README.txt has some basic advice regarding the setup of Unity.Mvc3 and can be deleted once you are familiar with the package. Bootstrapper.cs is the file containing the code to initialise the Unity container and DependencyResolver. When we come to add dependencies later in the article, we will need to register them in this class.
using System.Web.Mvc;
using Microsoft.Practices.Unity;
using Unity.Mvc3;
namespace MvcApplication1
{
public static class Bootstrapper
{
public static void Initialise()
{
var container = BuildUnityContainer();
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
}
private static IUnityContainer BuildUnityContainer()
{
var container = new UnityContainer();
// register all your components with the container here
// e.g. container.RegisterType<ITestService, TestService>();
container.RegisterControllers();
return container;
}
}
}
To hook up the Bootstrapper, we just need to edit the Application_Start method of the Global.asax and add a call to the static Initialise method.
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
Bootstrapper.Initialise();
}
We could have used the WebActivator NuGet package to automatically call the Bootstrapper.Initialise method at application startup, but doing this makes the code a little less understandable. Most developers know about the global.asax and can more easily work out what is going when we add the call manually to Application_Start.
You can now run the application and whilst you will not notice any difference to the user interface, behind the scenes, the controllers are now being resolved via Unity. How very exciting :-)
Adding a dependency
So now that we have Unity hooked into the MVC pipeline, we can actually start injecting some components into our controller. We are going to inject a (very) simple message service. When injecting components, we normally work with abstractions rather than concrete types, so first we create an IMessageService interface and then implement the interface in the MessageService class. namespace MvcApplication1 { public interface IMessageService { string GetMessage(); }
public class MessageService : IMessageService
{
public string GetMessage()
{
return "Hello from the MessageService";
}
}
}
Now, let's change the HomeController so it uses this component. We will use constructor injection which is the preferred method of dependency injection, particularly if the component must always be supplied as opposed to an optional component which may be injected via a property. So, we add a new constructor that takes in an IMessageService. To visually see that the components gets injected properly, we will change the Index action to use the GetMessage method of the service and output the result to the View (via the ViewBag which I would normally avoid and use strongly typed view models instead but it is fine for this demonstration).
using System.Web.Mvc;
namespace MvcApplication1.Controllers
{
public class HomeController : Controller
{
private readonly IMessageService _messageService;
public HomeController(IMessageService messageService)
{
_messageService = messageService;
}
public ActionResult Index()
{
ViewBag.Message = _messageService.GetMessage();
return View();
}
public ActionResult About()
{
return View();
}
}
}
The last thing we need to do is to let Unity know about the MessageService. This is done by registering the component in the BuildUnityContainer method of the Bootstrapper class. Notice that we are using the RegisterType<TFrom, TTo> overload that allows us to map the IMessageService interface to the concrete MessageService class.
private static IUnityContainer BuildUnityContainer()
{
var container = new UnityContainer();
container.RegisterType<IMessageService, MessageService>();
container.RegisterControllers();
return container;
}
If you build and run the application at this point, you will see something similar to Figure 5 below. The DependencyResolver is being asked by the MVC framework to return a HomeController. The resolver uses Unity to work out that the HomeController constructor requires an IMessageService dependency to be satisfied. Unity knows about this interface and instantiates the concrete MessageService type which is then injected into the controller and returned to the MVC framework. Then in the Index action method, the GetMessage method of the injected IMessageService is called and the result added to the ViewBag and rendered on the page. Congratulations, you are doing dependency injection in MVC3!
Figure 5: MVC View Displaying The Message Created By The The MessageService
Adding a dependency for the dependency
Let's make it a little bit more complicated by assuming that the MessageService has a dependency itself so when we resolve the HomeController, we need to inject an IMessageService as before, but the MessageService constructor now takes in an IMessageGenerator. Again we create an interface and concrete type.
namespace MvcApplication1
{
public interface IMessageGenerator
{
string GetMessage();
}
public class MessageGenerator : IMessageGenerator
{
public string GetMessage()
{
return "Hello from the MessageGenerator";
}
}
}
Now we need to change the MessageService so it takes in the IMessageGenerator as a constructor argument. We will also change the GetMessage method so it uses the IMessageGenerator and also appends some text itself so we can see that the output has come from the MessageGenerator via the MessageService.
public class MessageService : IMessageService
{
private readonly IMessageGenerator _messageGenerator;
public MessageService(IMessageGenerator messageGenerator)
{
_messageGenerator = messageGenerator;
}
public string GetMessage()
{
return string.Concat(_messageGenerator.GetMessage(), " via the MessageService");
}
}
Once again, we need to register the new component with Unity in the Bootstrapper:
container
.RegisterType<IMessageService, MessageService>()
.RegisterType<IMessageGenerator, MessageGenerator>();
Run the application and this time, the message should have changed to what is shown in Figure 6. If you are not familiar with dependency graph resolution, then you might be pleasantly surprised by this functionality. This is one of the reasons why IoC containers can be so useful. It is common to have dependency graphs many levels deep and it is very useful to be able to resolve the whole graph automatically.
Figure 6: MVC View Displaying The Message Created By The The MessageService And MessageGenerator
IDisposable dependencies
The final example that we are going to look at is the case where a dependency implements IDisposable. In the vast majority of cases, if you are dealing with a disposable component in the context of an MVC application, you want to create the component at the start of the request and dispose of it at the end of the request. The obvious and extremely common example is the ORM context or session that functions as your unit of work. Whether you use NHibernate, Entity Framework or LINQ to SQL, you must dispose of your context/session at the end of the request. The original article goes into more detail about how the Unity.Mvc3 DepenendencyResolver disposes of components, but as a consumer of the package, all you really need to know is how to instruct the resolver to treat a component as disposable.
For this example, we will assume that MessageGenerator implements IDisposable. We have nothing to actually dispose of so we will just output some text so we can see that the method is called. using System; using System.Diagnostics;
namespace MvcApplication1
{
public interface IMessageGenerator
{
string GetMessage();
}
public class MessageGenerator : IMessageGenerator, IDisposable
{
public string GetMessage()
{
return "Hello from the MessageGenerator";
}
public void Dispose()
{
Debug.WriteLine("Message Generator is being disposed");
}
}
}
To indicate to the dependency resolver that you want to dispose of a component, all you need to do is register it using the HierarchicalLifetimeManager. Again, I wrote about this in the previous Unity.Mvc3 article and you can find out more by reading that.
container
.RegisterType<IMessageService, MessageService>()
.RegisterType<IMessageGenerator, MessageGenerator>(new HierarchicalLifetimeManager());
Run the application and check the output window and you can see that every request, Dispose is called on the MessageGenerator. Whilst it might not be the most exciting demonstration, it is vital that you dispose of components properly to avoid memory leaks and connection timeouts.
Figure 7: Output Window Showing Message When MessageGenerator Is Disposed
Conclusion
Unity.Mvc 1.1 now targets the recently released Unity 2.1. The NuGet has been modified to have a dependency on the Unity NuGet package meaning that if you install Unity.Mvc without having Unity, it will automatically be downloaded and added to your project. A Bootstrapper has also been added to the package to decrease the number of steps necessary to integrate Unity.Mvc into your solution. This article includes a comprehensive walkthrough for getting users up to speed and provides several examples for adding dependency injection to MVC in a correct manner.
This is awesome, thanks!
Hi,
Great article and package. I am developing a MVC web app was worried about the DataContext lifetime. I was thinking of swapping to Niject DI as that has a HttpRequest lifetime but I wanted to stay with Unity as I plan to use Validator injection. I was hunting for a solution and fell across your work by accident. Glad I did.
I do have a question though. I have a number of types, like loggers, that are thread safe and I currently instantiate and insert as instances. Will these keep being lost/recreated with the ChildContainer, and if so does it matter (performance/speed??)?
Thanks again
Jon Smith
PS. I rated the package 5*. Worth people finding it
@Jon - Glad you like it.
You do not need to worry about the instances. When you use the RegisterInstance method, Unity uses the ContainerControlledLifetimeManager by default. This lifetime treat the component as a singleton for the parent container, so despite child containers being created and destroyed per request, your instances will only be created once for the lifetime of the application. Using RegisterType and explicitly setting the lifetime to ContainerControlledLifetimeManager will have the same effect.
Hi Paul,
I am refactoring my application to use your Unity.Mvc3 module and I have some questions.
I am using Unit Tests and I when checking Unity I want to create/destroy the Unity Container and associated items in [SetUp] and [TearDown]. However you seem to use a number of static classes/methods, like PreApplicationStartCode and Bootstrapper. Clearly I can work round Bootstrapper but not PreApplicationStartCode (but does it matter). You didn't include any Unit Tests in the source code, but I see you generally use them so any comments would be helpful.
The other questions are more about why you have done some things as I am not as up to speed on Unity as you are:
1. Why do you use DynamicModuleUtility.RegisterModule to register RequestLifetimeHttpModule? MSDN doc says this isn't for general use so I don't know what it does. Why do you need it?
2. I don't quite see why you need to register the type of all the controllers (method RegisterControllers). Is that so that the statement in GetService
if (typeof(IController).IsAssignableFrom(serviceType))
will work? Why won't it work without registering the controller types? In my current usage of Unity (pre installing your Unity.Mvc3) I don't register the controller types and it works.
Thanks for your help on this.
Jon Smith
Selective Analytics
Hi Paul,
Sorry, I should have googled a bit more before asking about DynamicModuleUtility.RegisterModule. I now see what is happening: you register RequestLifetimeHttpModule to catch the INIT call at the start of a web request and clear out the old child container. Clearly that is how you create the PerHttpRequest lifetime container. Neat.
Jon Smith
Selective Analytics
Hi Paul,
Thanks for the input on Unit Testing. I, like you don't use DI in my unit tests. I saw your article 'How not to do dependency injection - configuring the IoC container in unit test projects' and I totally agree. However I wanted to check that a) My Unity configuration is OK (I have had problems), b) that Unity.Mvc3 was installed and working and c) check from problems between Unity.Mvc3 setup and a Unity interception policy (again, I had a problem there that needed fixing).
The problem with unit testing Unity.Mvc3 is that it relies on HttpContext.Current. You kindly suggested a method to fake this which I included in the test fixture setup (see code below for NUnit. Note it needs a number of using statements: System.IO, System.Web and System.Web.Hosting)
[TestFixtureSetUp]
public void Setup()
{
//generate test httpcontext. Needed by Unity.Mvc3
var httpWorkerRequest = new SimpleWorkerRequest("/test", "c:\\inetpub\\wwwroot\\test\\", "/", "", new StringWriter());
HttpContext.Current = new HttpContext(httpWorkerRequest);
}
With this in place and the creation of a new Unity.Mvc3 resolver every time then DI works fine. However the dispose of the child container isn't called as there is no HttpRequest pipeline, so to test that I called your static method DisposeOfChildContainer directly to check the dispose happens. Maybe not perfect but I am very happy with that.
Jon Smith
Selective Analytics
Is it possible to register an instance with unity / unity,mvc3, so that it has a per request lifetime? When I try register instance with HierarchicalLifetimeManager I receive the error:
The current type, NHibernate.ISession, is an interface and cannot be constructed. Are you missing a type mapping?
@Chris - As Nadine wrote on StackOverflow, if you want an object on a per request basis then you should not use RegisterInstance. Instead, use RegisterType with a factory:
Container.RegisterType<ISession>(new InjectionFactory(c => SessionFactory.OpenSession()), new HierarcicalLifetimeManager());
Why do I need to register the controllers with the "RegisterControllers" extension method? Do I need it at all or is it optional? When I register my dependencies without registering the controllers themselves everything seems to work fine. When is it required to register the controllers or which benefit does it have?
@Tom and Jon - RegisterControllers is not necessary and will be removed when I get a chance. Unlike some IoC containers, Unity is able to resolve components that are not actually registered provided that all dependencies can be satisfied.
It was originally necessary because IDependencyResolver implementations are supposed to return null if a resolution is not possible. The nicest way to do this (without catching exceptions) is to use the container's IsRegistered method and ensure that all components are registered. However, doing this often results in rather cryptic errors messages if the container configuration is incorrect, particularly for controllers. Therefore, I added logic to just try and resolve controllers without checking for registration, fixing the error message issue and also making RegisterControllers unnecessary.
Great article and this is a very clean way of ensuring that dependencies are disposed of correctly.
I've been playing with this code for a good few hours today and have a general observation:
This implementation relies on the Application_EndRequest method to clear down the Unity child container. If the setting "runAllManagedModulesForAllRequests" in the web.config is "false" then this method won't be called and therefore the child container won't be cleared down. The "runAllManagedModulesForAllRequests" is often set to "false" for the performance benefits of ensuring requests to static content aren't relayed through the pipeline so this might be an issue for some people?
In this scenario, is there a clean way the Unity child container could be cleared down?
Hi Paul,
Thanks for the nice article and the library. I have one question, Can this Unity.MVC3 be used for Asp.Net Web Forms project? If so, can you briefly direct me how to do it?
Thank you.
Don't you have any plans for MVC 4?
There is an issue with Unity.MVC3. It uses the Unity method IsRegistered() which has been deemed "NOT FIT FOR PRODUCTION" by the authors of Unity. Please see here [https://unity.codeplex.com/discussions/268223]
It would be nice if this is fixed in a future release.
Thanks
@Benkai - Thanks. It is interesting that one of the Unity team says that IsRegistered is 'intended for debugging your apps only' when there is no mention of this fact in the documentation. Nevertheless, in this particular case, the alternative would be to try to resolve regardless and then catch the exception (in order to return null as per DependencyResolver requirements) which would be considerably slower. Given the timings mentioned, we are talking about milliseconds for a typical graph resolution so it is really not worth worrying about IMO.