ASP.NET 5 vNext Dependency Injection

I spent the whole day going around in circles attempting to fix an application that I broke. It’s not the first time, and I’m sure it won’t be the last.

It’s a pet application of mine that I work on from time to time to keep up to date with the latest Visual Studio and ASP.NET features. I thought it would be a good idea to upgrade from MVC 4 to 5, as a precursor to porting the solution across to Visual Studio 2015. So off I went half-cocked and installed the ASP.NET MVC 5.2.2 NuGet package, which in turn upgraded WebPages and Razor from version 2 to version 3. But in typical, if it ain’t broke then don’t fix it, style my application imploded and refused to compile. A couple of hours later and it was compiling, but Unity was no longer resolving dependencies even though the types were correctly registered in the container. Bottom line was that the version of Unity that I was using depended on version 2 of WebPages and Razor, and as such does not sit well with MVC 5. Once I had worked this out, I was able to upgrade Unity and all was well.

I did not really put a great deal of thought into the upgrade. If I had I would have realized that what I should be doing is porting the MVC 4 solution across to Visual Studio 2015 and then upgrading to MVC 5, whilst removing Unity completely. The reason being is that one of the neat features that will be introduced with ASP.NET 5 is out-of-the-box dependency injection. And out-of-the-box means no need to shoe-horn 3rd party packages/assemblies into the solution – unless you really want to.

What I’d like to demonstrate is the steps you need to take to implement Unity for constructor injection in an MVC 4 project, and how the ASP.NET 5 out-of-the-box dependency injection makes life a whole lot easier.

Implementing Unity in an MVC 4 project

Create a new ASP.NET MVC 4 and install the Unity Bootstrapper package

I’m using Visual Studio 2013 for this demo. If you have Visual Studio 2012 then the steps and outcomes should be the same, although I haven’t tested this. If you have Visual Studio 2010 SP1 then in theory you can download the MVC 4 framework. But it’s probably better to request an upgrade. Although I appreciate that this is not always possible given company and project constraints.

Create a new Visual C# ASP.NET project, and then instal the Unity Bootstrapper for ASP.NET MVC NuGet package –

NuGet Unity

The Unity Bookstrapper package adds 2 class libraries to the App_Start folder – UnityConfig.cs and UnityMvcActivator.cs –

Unity Solution

UnityMvcAcvtivator.cs

The UnityMvcActivator class manages the life-time of the Unity container. It utilises the WebActivatorEx module to instantiate and configure the container during application start-up, and to dispose of the container during shut-down,

An alternative to using WebActivatorEx is to modify the Global.asax Application_Start and Application_End events to instantiate and dispose of the container. However, NuGet cannot do this automatically. It is something you would have to code manually.

UnityMvcActivator

The Start() method is executed during application start-up. The key point to getting Unity up and running is that UnityWebActivator calls the UnityConfig.GetConfiguredContainer() method to get a configured Unity container to use when resolving dependencies. We need to tell the system how to resolve the dependencies. We do this by registering the types – which we will do next.

UnityConfig.cs

The GetConfiguredContainer() method returns an instantiated Unity container that includes the details of which concrete types to instantiate when it instantiates an object that requires the injection of an interface.

In the example code below I have registered ProductService as the concrete implementation of IProductService.

UnityConfig

In the next section I will implement IProductService, and ProductService. I will then modify the HomeController to require IProductService to be injected into it’s constructor. And then show that the dependency injection is working as expected.

IProductService and ProductService

To keep things simple, the IProductService interface exposes a single method, WhoIAm(), which returns a string.

IProductService

The ProductService class implements this method, returning “I am product service”.

ProductService

Injecting IProductService into HomeController

I have modified HomeController as follows –

  • Added _productService as a private field of type IProductService
  • Added a constructor which receives an instance of IProductService, and assigns this instance to the _productService field.
  • Modified the Index() method to return the result of the _productService.WhoIAm() call.

HomeController

Running the Project

Running the project results in the following action result from the Home/Index method –

UnityResult

This proves that Unity is correctly injecting an instance of the concrete ProductService class into the HomeController constructor.

It’s as easy as that. And it gets even easier with ASP.NET 5 out-of-box dependency injection.

Implementing Dependency Injection in an ASP.NET 5 vNext MVC Project

For this example I’m going to boot up Visual Studio 2015 preview.

This time I’m going to create a new ASP.NET 5 vNext Starter Web project.

New vNext Project

IProductService, ProductService, and HomeController changes

I created the same IProductService and ProductService classes. And injected the IProductService class into the HomeController’s constructor. So exactly the same code as before.

IProductService

ProductService

HomeController

As an aside, check out the hints telling us how many references each class and method has. This is a by-product of another really neat vNext feature – dynamic compilation.

Register the ProductService Type

As the dependency injection is out-of-the-box we do not need to install and configure any packages. All we need to do is register our concrete types.

The Startup class has a ConfigureServices method. The runtime calls this method, and passes through an instance of a class which implements the Microsoft.Framework.DependencyInjection.IServiceCollection interface.

All we need to do register the ProductService type, with the instance of IServiceCollection, as the concrete implementation for IProductService –

 services.AddTransient<IProductService, ProductService>();

Startup

And Bob’s your Uncle

Results

So the out-of-the-box implementation works – as it’s name suggests – straight out-of-the-box, without the need to install additional dependencies, or create the code to manage the life-cycle of the dependency injection container. All that is required is for the concrete types to be registered.

One thing to note is that at the time of writing vNext only supports constructor injection. It does not support property setter or method call injection. Not that this is an issue for me, as I only ever use constructor injection.

Advertisements