ASP.NET MVC and Unity IoC


Since several years, software are becoming increasingly complex. A technique to simplify the maintenance is to use a design pattern that allows to remove the dependencies to difficult parts of the software (loosely-coupled design). The Dependency Injection Pattern is part of these techniques. In this post, I explain how to use the Unity framework in an ASP.NET MVC project.

The main objective of the IoC is to use the Unity framework to register Model Objects, based on the environment where it is used: for production (DataService), for development (DesignDataService) or for unit tests (TestDataService). Whenever a Controller need data from the model, we call a Resolver method (included in my UnityLocator class) that returns the good instance of this model, based on this environment. So, with a simple flag (#DEBUG, IsDesignMode property, …) you can switch from a Design environment to a Production environment. Another interesting point is for Unit Testing, where you can define your sample data in a TestDataService class to validate all of your methods.

To integrate Unity in a ASP.NET project, you can use existing packages like Unity.Mvc, but I prefer define my lightweight class to have all control on it.

  1. The first step is to add Microsoft Unity in your existing ASP.NET MVC project.

    Select the command Project / Manage NuGet Packages and search Unity 4.0 (or more).

  2. Add a new project ‘Class Library’ where all Models and ViewModels (adaptation of your models to your applications, your views).

  3. In your Model library, add an interface IDataService that will be implemented by the production service (SqlDataService) and the development service (DesignDataService).

  4. In your ASP.NET MVC project:
    (these classes are downloadable here).
    1. Add a reference to you Model library (to use IDataService).
    2. Create a class UnityResolver to manage the Unity framework, with a ‘container’ for your application.
    3. Create a class A UnityDependencyResolver used by ASP.NET MVC, in Global.asax.cs and the Mvc.DependencyResolver.Current property embedded by MVC.
    4. Create a class A UnityLocator to resolve all ViewModels or Models in a single class.

  5. The UnityLocator is the main custom class to register all ViewModels (or Models) and to be referenced by the Global.ascx.cs.
private UnityContainer _container = new UnityContainer();

public UnityLocator()
{
    // Self registration to use it later
    _container.RegisterInstance<UnityLocator>(this);

    // Registration of DataService
    //_container.RegisterType<IDataService, DesignDataService>();
    _container.RegisterType<IDataService, SqlDataService>();

    // Registration of all ViewModels
    _container.RegisterType<HomeViewModel>();
}

public HomeViewModel Home
{
    get
    {
        return _container.Resolve<HomeViewModel>();
    }
}

public UnityDependencyResolver UnityDependencyResolver
{
    get
    {
        return new UnityDependencyResolver(_container);
    }
}

6. Next, you need to include de DependencyResolver in MVC framework global.ascx.cs file.

protected void Application_Start()
{
    // Create and register the IoC Unity resolver
    DependencyResolver.SetResolver(new UnityLocator().UnityDependencyResolver);

    AreaRegistration.RegisterAllAreas();
    RouteConfig.RegisterRoutes(RouteTable.Routes);
}

7. Finally, you can use your Data objects in all Controllers. To simplify my code, I’ve created a ControllerBase class with a property Locator.

public abstract class ControllerBase : Controller
{
    public UnityLocator Locator
    {
        get
        {
            return DependencyResolver.Current.GetService<UnityLocator>();
        }
    }
}

public class HomeController : ControllerBase
{
    public ActionResult Index()
    {
        var home = this.Locator.Home;
        return View(home);
    }
}

So, you have a separated library with all Models and ViewModels (without references to your UI or Unity framework).
You can create sample data in DesignDataService class, or mokup data in TestDataService for Unit Testings.
In a future evolution, you can remove the reference between your ASP.NET MVC project and your Model library, using a configuration file to load dynamically your data models (but I think that is too complex in a first step).

Source code including a sample of this implementation is here : https://github.com/dvoituron/DevAppsPodcast

Resources: https://unity.codeplex.com and http://amzn.com/B00EO89ZM8

Advertisements
Posted in ASPNET, IoC, MVVM
4 comments on “ASP.NET MVC and Unity IoC
  1. Hi Denis,

    What you are doing effectively here is creating a ServiceLocator. ServiceLocator is an Anti-Pattern (check http://blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern/). You might want to favour constructor or property injection instead.

    Also, beware about the difference DI & IoC : Inversion of Control is a design principle, DI is just one application of it in the form of a design pattern. The most important of the two is IoC which encourages you to surface the dependencies in your software component design.

    Steve (mi8)

  2. Hello Steve,

    Thanks for your comment, very interesting… Yes, when we develop with IoC, the question about ServiceLocator is coming. And how to use it (anti-pattern or not). Many articles describe the ServiceLocator as an anti-pattern (http://blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern/) or not (http://blog.gauffin.org/2012/09/28/service-locator-is-not-an-anti-pattern) 😉

    Another point is about this feature (DependecyResolver) natively included in MVC… and also discussions about Why (http://stackoverflow.com/questions/9409068/why-is-mvc4-using-the-service-locator-anti-pattern).

    This article is only a tutorial to use Unity and how to link it to the DependencyProperty feature of MVC.

    Denis

  3. Arnaud Weil says:

    Hello,

    My own point of view is that everything should be as simple as it can be. Dependency injection solves two problems: having duplicate mockups class (the one you target), and having a way to “ask for” dependencies instead of creating them.

    I love depencency injection for solving those two aspects. However, because of the increasead complexity I’d recomment using it only when the requirements need those two aspects.

    One simplification I make though is not to reference the sevice locator from the ViewModel. I use MEF (which shouldn’t change anything) and simply us the DependencyResolver.SetResolver call to tell ASP.NET MVC to use MEF for DI. Then it’s just a matter of placing an [Export] attribute on each controller, and applying [Import] attributes on injected properties Inside the controllers. Simple, hence beautiful.

  4. I prefer the foundational posts about IoC & DI from 10 years ago to the rehashed posts from 2-3 years ago 😉
    http://www.jroller.com/hammett/date/20050416
    http://www.martinfowler.com/articles/injection.html

    The problem with ServiceLocator is that you introduce a dependency to a concrete class at the type system-level, while if you favor IoC as a base design principle, that is using pure OO language constructs, the only dependencies you expose via either constructor (mandatory) / property (optional) can be reduced to just interface definitions (contracts).

    Also, something devs often forget (or don’t know about), coupling has a 5 dimensions : afferent, efferent, platform, temporal, spatial. So when talking about loose-coupling, you want to consider the 5 dimensions, not just the type system-related coupling. DI doesn’t help there (it’s just about “injecting stuff”), IoC might.

    IoC (as a principle, not IoC Container as a library / component) encourages you to think about your design (cfr. dependency map, coupling metrics). I find it more valuable to think from that perspective than from a specific implementation (Unity, MEF, DependencyResolver, etc).

    Those concepts are 10 years old, and mind you, ASP.NET MVC is certainly not a good example of proper software design (e.g. favoring simplicity). OWIN or ASP.NET 5 are finally going in the right direction though.

    Note: The chosen answer as to why MVC is using ServiceLocator (http://stackoverflow.com/questions/9409068/why-is-mvc4-using-the-service-locator-anti-pattern) is pretty lame. I like the answers from Mark Seemann though 🙂

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow me
   RSS Feed    Twitter    Linked In

Write you email address to subscribe at this blog and to receive new posts by mail.

Join 565 other followers

Who I am?






%d bloggers like this: