Dependency Injection for Multiple Concrete Implementations of an Interface

Dependency Injection and Inversion of Control (IoC) are one of the key players in todays web architectures. DI improves code reusability and guarantees loosely coupled systems. Having a DI onboard will help in both code maintenance perspective and application testing.

Following tutorial narrates on how use Unity Container (typically an IoC) with ASP.Net MVC4 web project. At a glance we will see how to setup Unity container along with its implementation on multiple concrete implementations of an interface.

Lets get started by creating a MVC4 web project in VS 2012. Name it as DIWeb. Select WebAPI template. Now create one more Classlibrary in the solution. Name it as DIOperations.

Create IPerson interface in DIOperations as shwon below –

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DIOperations
{
    public class Person
    {
        public string name { get; set; }
        public int age { get; set; }
    }
    public interface IPerson
    {
        Person GetPerson();
    }
}

Create two classes Male and Female, which implements IPerson interface.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DIOperations
{
    public class Male : IPerson
    {
        public Person GetPerson()
        {
            return new Person() { name = "Rami", age = 25 };
        }
        // Some other Male Specific Properties and Methods
    }
    public class Female : IPerson
    {
        public Person GetPerson()
        {
            return new Person() { name = "Jash", age = 21 };
        }
        // Some other Male Specific Properties and Methods
    }
}

Compile DIOperations and add the compiled DLL as a reference to DIWeb project. Now right click DIWeb Project and select Manage Nuget Packages. Select Online, and search for Unity.

 

DI1

 

Select Unity.Mvc3 and click install. On accepting terms and conditions, Unity Container will be installed on DIWeb project. All the packages references will be updated in packages.config and all necessary DLL’s will be automatically referenced (simply WOW to the power of Nuget).

Open Global.asax and write the following statement in Application_Start event –

Bootstrapper.Initialise();

Then open Bootstrapper.cs and add the following registrations to BuildUnityContainer() method –

container.RegisterType<IPerson, Male>("Male");
container.RegisterType<IPerson, Female>("Female");

Lets lets dynamically inject these types to home Controller. Open HomeController.cs –

using DIOperations;
using Microsoft.Practices.Unity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace DIWeb.Controllers
{
    public class HomeController : Controller
    {
        private IPerson malePerson;
        private IPerson femalePerson;

        public HomeController([Dependency("Male")]IPerson malePerson, [Dependency("Female")]IPerson femalePerson)
        {
            this.malePerson = malePerson;
            this.femalePerson = femalePerson;
        }

        public ActionResult Index()
        {
            return View();
        }

        public ActionResult Male()
        {
            return View(malePerson.GetPerson());
        }

        public ActionResult Female()
        {
            return View(femalePerson.GetPerson());
        }
    }
}

Create corresponding views for Male() and Female() actions as below –

Male.cshtml –

@model DIOperations.Male

@{
    ViewBag.Title = "Male";
}

<h2>Male</h2>

<fieldset>
    <legend>Male</legend>

    <div class="display-label">
         @Html.DisplayNameFor(model => model.name)
    </div>
    <div class="display-field">
        @Html.DisplayFor(model => model.name)
    </div>

    <div class="display-label">
         @Html.DisplayNameFor(model => model.age)
    </div>
    <div class="display-field">
        @Html.DisplayFor(model => model.age)
    </div>
</fieldset>

Female.cshtml –

@model DIOperations.Female

@{
    ViewBag.Title = "Female";
}

<h2>Female</h2>

<fieldset>
    <legend>Female</legend>

    <div class="display-label">
         @Html.DisplayNameFor(model => model.name)
    </div>
    <div class="display-field">
        @Html.DisplayFor(model => model.name)
    </div>

    <div class="display-label">
         @Html.DisplayNameFor(model => model.age)
    </div>
    <div class="display-field">
        @Html.DisplayFor(model => model.age)
    </div>
</fieldset>

 

At this point we are done with all the setup for our Dependency injection. We can run the application and navigate to /home/male and /home/female urls in browser, seeing corresponding details.

Thus we have implemented a basic Dependency injection, in this way there is no need to change any of our dependent code of IPerson, If a new implementation comes, we can change it in Bootstrapper.cs and continue our application development without any breakages.

PS – Multiple concrete implementations may not be realistic in practical applications in real world. Aim of this tutorial is to show the possibility of referring multiple implementations of interface through DI.

You may also like...

2 Pingbacks/Trackbacks

  • Pingback: Blog Post from the Week (7th - 13th April 2013) - The South Asia MVP Blog - Site Home - TechNet Blogs()

  • Do you have more great artcelis like this one?

  • bnjkukunuri

    In above case, In conventional Factory method pattern – we pass the Male() or Female() object into constructor. In of IoC we use container to resolve it. I understand till part. But still in the scenario we are mentioning the actual concrete type [Dependency(“Male”)] using attributes, in future if we want to get it resolved to different implementation, we still need to come here and change the code to provide different class name like [Dependency(“MaleTenager”)] or [Dependency(“Girl”)]. I understand genders many have more implementations, but just for example.

  • ramiramilu

    [Dependency(“Female”)] can be driven through config file entry. Also we can resolve dependencies using XML Unity Configuration file as well. That’s how we get more loosely coupled system.

  • Pingback: Blog Post from the Week (7th – 13th April 2013) | India MVP Community()