In this exercise you will learn how to use Dependency Injection in MVC Controllers, by integrating Unity Application Block. For that reason you will include services into your MVC Music Store controllers to separate the logic from the data access. The service will create a new dependence into the controller constructor that will be resolved using Dependency Injection with the help of Unity application block.
With this approach you will learn how to generate less coupled applications, which are more flexible and easier to maintain and test. Additionally, you will also learn how to integrate MVC with Unity.
About StoreManager service
The MVC Music Store provided in the begin solution now includes a service that manages the Store Controller data, StoreService. Below you will find the Store Service implementation. Note that all the methods return Model entities.
| C# - StoreService.cs | Copy Code
|
|---|---|
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using MvcMusicStore.Models;
namespace MvcMusicStore.Services
{
public class StoreService : MvcMusicStore.Services.IStoreService
{
MusicStoreEntities storeDB = new MusicStoreEntities();
public IList<string> GetGenreNames()
{
var genres = from genre in storeDB.Genres
select genre.Name;
return genres.ToList();
}
public Genre GetGenreByName(string name)
{
var genre = storeDB.Genres.Include("Albums")
.Single(g => g.Name == name);
return genre;
}
public Album GetAlbum(int id)
{
var album = storeDB.Albums.Single(a => a.AlbumId == id);
return album;
}
}
}
| |
Additionally, the StoreController you will find in the begin solution now uses StoreService. All data references were removed from Store Controller, and therefore it is possible to modify the current data access provider without making changes at any method that consumes the Store Service.
You will find below that the Store Controller implementation has a dependency with the Store Service inside the class constructor.
Note: |
|---|
| The dependency introduced in this exercise is related to MVC Inversion of Control (IoC). The StoreController class constructor receives an IStoreService parameter, which is essential to perform service calls inside the class. However, StoreController does not implement the default constructor (with no parameters) that any controller must have to work with IoC. To resolve the dependency, the controller should be created by an abstract factory (a class that returns any object of the specified type). |
| C# - StoreController.cs | Copy Code
|
|---|---|
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MvcMusicStore.ViewModels;
using MvcMusicStore.Models;
using MvcMusicStore.Services;
namespace MvcMusicStore.Controllers
{
public class StoreController : Controller
{
private IStoreService service;
public StoreController(IStoreService service)
{
this.service = service;
}
//
// GET: /Store/
public ActionResult Index()
{
// Create list of genres
var genres = this.service.GetGenreNames();
// Create your view model
var viewModel = new StoreIndexViewModel
{
Genres = genres.ToList(),
NumberOfGenres = genres.Count()
};
return View(viewModel);
}
//
// GET: /Store/Browse?genre=Disco
public ActionResult Browse(string genre)
{
var genreModel =this.service.GetGenreByName(genre);
var viewModel = new StoreBrowseViewModel()
{
Genre = genreModel,
Albums = genreModel.Albums.ToList()
};
return View(viewModel);
}
//
// GET: /Store/Details/5
public ActionResult Details(int id)
{
var album = this.service.GetAlbum(id);
return View(album);
}
}
}
| |
Note: |
|---|
| You will get an error when a class tries to create this Store Controller without sending the service interface, because there is not a parameterless constructor declared.Through this lab you will learn how to deal with this problem using Dependency Injection with Unity. |
Task 1: Running the application
In this task you will run the Begin application, which is now including the service into the Store Controller that separates the data access from the application logic.
After browsing to the store you will receive an exception since the controller service is not passed as a parameter by default:
- Open the begin solution MvcMusicStore.sln at Source\Ex01-Injecting Controller\Begin
- Press F5 to run the application.
- Browse to /Store to load Store Controller. You will get the error message “No parameters constructor defined for this object”:

Figure 1
Error while running MVC Begin Application
In the following steps you will work on the Music Store Solution to inject the dependency this controller needs.
Task 2: Including Unity into MvcMusicStore solution
In this task you will include Unity Application Block 2.0 into your solution.
Note: |
|---|
| The Unity Application Block (Unity) is a lightweight, extensible dependency injection container with optional support for instance and type interception. It’s a general-purpose container for use in any type of .NET application. It provides all the common features found in dependency injection mechanisms including: object creation, abstraction of requirements by specifying dependencies at runtime and flexibility, be deferring the component configuration to the container. You could read more about Unity 2.0 at msdn. |
- Open the begin solution MvcMusicStore.sln at Source\Ex01-Injecting Controller\Begin
- Add a new reference to Microsoft.Practices.Unity.dll, which is included in Source\Assets\Unity 2.0\
Task 3: Adding a Unity Controller Factory
In this task you will add to the solution a custom controller factory for Unity. This class implements IControllerFactory interface, extending CreateController and ReleaseController methods to work with Unity. This factory will create the instances of the controllers that work with Dependency Injection.
Note: |
|---|
| A controller factory is an implementation of the IControllerFactory interface, which is responsible both for locating a controller type and for instantiating an instance of that controller type. The following implementation of CreateController finds the controller by name inside the Unity container and returns an instance if it was found. Otherwise, it delegates the creation of the controller to an inner factory. One of the advantages of this logic is that controllers can be registered by name. You can find IControllerFactory interface reference at msdn. |
- Create a new folder Factories at project root and add the class “UnityControllerFactory.cs”, which is included in Source\Assets
C# - UnityControllerFactory.cs
Copy Code
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using Microsoft.Practices.Unity; using System.Web.Routing; namespace MvcMusicStore.Factories { public class UnityControllerFactory : IControllerFactory { private IUnityContainer _container; private IControllerFactory _innerFactory; public UnityControllerFactory(IUnityContainer container) : this(container, new DefaultControllerFactory()) { } protected UnityControllerFactory(IUnityContainer container, IControllerFactory innerFactory) { _container = container; _innerFactory = innerFactory; } public IController CreateController(RequestContext requestContext, string controllerName) { try { return _container.Resolve<IController>(controllerName); } catch (Exception) { return _innerFactory.CreateController(requestContext, controllerName); } } public void ReleaseController(IController controller) { _container.Teardown(controller); } public System.Web.SessionState.SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, string controllerName) { return System.Web.SessionState.SessionStateBehavior.Default; } } }
Note:This factory class can be reused in any project that uses Dependency Injection for Controllers.
Task 4: Registering Unity in Global.asax.cs Application_Start
In this task you will register Unity library into Global.asax.cs Application Start.
- Open Global.asax.cs at project root
- Include Microsoft.Practices.Unity Application Block, and references to the namespaces Services, Factories and Controllers:
(Code Snippet – ASP.NET MVC Dependency Injection –Ex1 Injecting Controllers Global using– Csharp)
C#
Copy Code
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using System.Web.Routing; using Microsoft.Practices.Unity; using MvcMusicStore.Services; using MvcMusicStore.Factories; using MvcMusicStore.Controllers;
- Create a new Unity Container in Global.asax.csApplication_Start and register the Store Service and the Store Controller.
(Code Snippet – ASP.NET MVC Dependency Injection –Ex1 Injecting Controllers Unity Container – Csharp)
C#
Copy Code
… protected void Application_Start() { AreaRegistration.RegisterAllAreas(); RegisterGlobalFilters(GlobalFilters.Filters); RegisterRoutes(RouteTable.Routes); var container = new UnityContainer(); container.RegisterType<IStoreService, StoreService>(); container.RegisterType<IController, StoreController>("Store"); } … - Register a UnityControllerFactory of the previous container inside MVC ControllerBuilder as the current factory for the controllers :
(Code Snippet – ASP.NET Dependency Injection – Ex1 Injecting Controllers Global application start)
C#
Copy Code
… protected void Application_Start() { AreaRegistration.RegisterAllAreas(); RegisterGlobalFilters(GlobalFilters.Filters); RegisterRoutes(RouteTable.Routes); var container = new UnityContainer(); container.RegisterType<IStoreService, StoreService>(); container.RegisterType<IController, StoreController>("Store"); var factory = new UnityControllerFactory(container); ControllerBuilder.Current.SetControllerFactory(factory); } …
Note:ControllerBuilder is an MVC class responsible for dynamically building a controller.
You can read more about ControllerBuilder at msdn.
Task 5: Running the application
In this task you will run the application to verify that the Store can now be loaded after including Unity.
- Press F5 to run the application.
- Browse to /Store. This will invoke StoreController, which is now created by using UnityControllerFactory.

Figure 2
MVC Music Store
In the following exercises you will learn how to extend the Dependency Injection scope, and use it inside MVC Views and Action Filters.