RESTful Day 2: Inversion of Control Using Dependency Injection in Web API's Using Unity Container and Bootstrapper

Introduction

This article explains how to make our Web API service architecture loosely coupled and more flexible. We already learned how to create a RESTful service using the ASP.Net Web API and Entity framework in my last article. If you remember, we ended up with a solution with a design flaw, we'll try to overcome that flaw by resolving the dependencies of dependent components. Those who have not followed my previous article can learn by having the sample project attached as a test application from my first article.

 Test application

Image source: https://www.pehub.com/wp-content/uploads/2013/06/independent-300x200.jpg

There are various methods you can use to resolve the dependency of components. In this article, I'll explain how to resolve a dependency using Unity Container provided by Microsoft's Unity Application Block.

We'll not go into very detailed theory, for theory and understanding of DI and IOC, you can use the following links: Unity and Inversion of Control(IOC). We'll straight away jump into a practical implementation.

Roadmap

Roadmap

Our roadmap for learning RESTful APIs remains the same; it is.

I'll purposely use Visual Studio 2010 and .NET Framework 4.0 because there are a few implementations that are very hard to find in .NET Framework 4.0, but I'll make it easy by showing how to do it.

Existing Design and Problem

We already have an existing design. If you open the solution, you'll get to see the structure as shown below.

 Solution

The modules are dependent in a way.

Modules

There is no problem with the structure, but the way they interact with each other is really problematic. You must have noticed that we are trying to communicate with layers, making the physical objects of classes.

For example, the Controller's constructor makes an object of the Service layer to communicate as in the following.

/// <summary>
/// Public constructor to initialize product service instance
/// </summary>
public ProductController()
{
    _productServices = new ProductServices();
}

The Service constructor in turn makes an object of UnitOfWork to communicate with the database as in the following.

/// <summary>
/// Public constructor.
/// </summary>
public ProductServices()
{
    _unitOfWork = new UnitOfWork();
}

The problem lies in these portions of code. We see the Controller is dependent upon instantiation of the service and the service is dependent upon UnitOfWork to be instantiated. Our layers should not be that tightly coupled and should be dependent on each other.

The work of creating an object should be assigned to someone else. Our layers should not worry about the creation of objects.

We'll assign this role to a third party that will be called our container. Fortunately, Unity provides that help to us, to eliminate this dependency problem and invert the control flow by injecting a dependency, not by creating objects but by using constructors or properties. There are other methods too, but I am not going into detail.

Introduction to Unity

You can have a read about Unity from this link, I am just quoting some lines.

Unity

Image source: http://img.tradeindia.com/fp/1/669/664.jpg

“The Unity Application Block (Unity) is a lightweight, extensible dependency injection container that supports constructor injection, property injection, and method call injection. It provides developers with the following advantages.

  • It provides simplified object creation, especially for hierarchical object structures and dependencies that simplify application code.
  • It supports the abstraction of requirements; this allows developers to specify dependencies at run time or in configuration and simplifies the management of crosscutting concerns.
  • It increases flexibility by deferring component configuration to the container.
  • It has a service location capability; this allows clients to store or cache the container. This is especially useful in ASP.NET Web applications where developers can persist the container in the ASP.NET session or application.”

Setup Unity

Open your Visual Studio, I am using Visual Studio 2010, you can use Visual Studio version 2010 or above. Load the solution.

Step 1. Browse to Tools -> Library Packet Manager - > Packet Manager Console as in the following.

Packet Manager

We'll add a package for a Unity Application Block.

In the bottom-left corner of Visual Studio, you'll find where to write the command.

Type the command Unity.MVC3 and choose the “WebApi” project before you fire the command.

WebApi

Step 2. Now for the Bootstrapper class.

Unity.MVC3 comes with a Bootstrapper class. As soon as you run the command, the Bootstrapper class will be generated in your WebAPI project as in the following.

using System.Web.Http;
using System.Web.Mvc;
using BusinessServices;
using DataModel.UnitOfWork;
using Microsoft.Practices.Unity;
using Unity.Mvc3;

namespace WebApi
{
    public static class Bootstrapper
    {
        public static void Initialise()
        {
            var container = BuildUnityContainer();
            DependencyResolver.SetResolver(new UnityDependencyResolver(container));
            // register dependency resolver for WebAPI RC
            GlobalConfiguration.Configuration.DependencyResolver = new Unity.WebApi.UnityDependencyResolver(container);
        }
        private static IUnityContainer BuildUnityContainer()
        {
            var container = new UnityContainer();

            // register all your components with the container here
            // it is NOT necessary to register your controllers

            // e.g. container.RegisterType<ITestService, TestService>();
            container.RegisterType<IProductServices, ProductServices>().RegisterType<UnitOfWork>(new HierarchicalLifetimeManager());

            return container;
        }
    }
}

=Bootstrapper

This class comes with an initial configuration to set up your container. All the functionality is built in, we only need to specify the dependencies that we need to resolve in the “BuildUnityContainer”, as it says in the commented statement in the following.

// register all your components with the container here
// it is NOT necessary to register your controllers

// e.g. container.RegisterType<ITestService, TestService>();

Step 3. Just specify the components below these commented lines that we need to resolve. In our case, it's ProductServices and UnitOfWork, so just add.

container.RegisterType<IProductServices, ProductServices>()
    .RegisterType<UnitOfWork>(new HierarchicalLifetimeManager());

"HierarchicalLifetimeManager", for this lifetime manager, as for the ContainerControlledLifetimeManager, Unity returns the same instance of the registered type or object each time you call the Resolve or ResolveAll method or when the dependency mechanism injects instances into other classes. The distinction is that when there are child containers, each child resolves its own instance of the object and does not share one with the parent. When resolving in the parent, the behavior is like a container-controlled lifetime; when resolving the parent and the child you have different instances with each acting as a container-controlled lifetime. If you have multiple children, each will resolve its own instance.

If you don't find “UnitOfWork”, just add a reference to the DataModel project in the WebAPI project.

So our Bootstrapper class becomes.

public static class Bootstrapper
{
    public static void Initialise()
    {
        var container = BuildUnityContainer();

        DependencyResolver.SetResolver(new UnityDependencyResolver(container));

        // register dependency resolver for WebAPI RC
        GlobalConfiguration.Configuration.DependencyResolver = new Unity.WebApi.UnityDependencyResolver(container);
    }

    private static IUnityContainer BuildUnityContainer()
    {
        var container = new UnityContainer();

        // register all your components with the container here
        // it is NOT necessary to register your controllers

        // e.g. container.RegisterType<ITestService, TestService>(); 
        container.RegisterType<IProductServices, ProductServices>().RegisterType<UnitOfWork>(new HierarchicalLifetimeManager());

        return container;
    }
}

That, we can also specify other dependent objects in BuildUnityContainerMethod.

Step 4. Now we need to call the Initialise method of the Bootstrapper class. Note, we need the objects as soon as our modules load, therefore we require the container to do its work when the application loads, therefore go to the Global.asax file and add one line to call the Initialise method. Since this is a static method, we can directly call it using the class name as in the following.

Bootstrapper.Initialise();

Our global. asax becomes.

using System.Linq;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using Newtonsoft.Json;
using WebApi.App_Start;

namespace WebApi
{
    // Note: For instructions on enabling IIS6 or IIS7 classic mode,
    // visit http://go.microsoft.com/?LinkId=9394801

    public class WebApiApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            
            // Initialise Bootstrapper
            Bootstrapper.Initialise();
            
            // Define Formatters
            var formatters = GlobalConfiguration.Configuration.Formatters;
            var jsonFormatter = formatters.JsonFormatter;
            var settings = jsonFormatter.SerializerSettings;
            settings.Formatting = Formatting.Indented;
            // settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
            var appXmlType = formatters.XmlFormatter.SupportedMediaTypes.FirstOrDefault(t => t.MediaType == "application/xml");
            formatters.XmlFormatter.SupportedMediaTypes.Remove(appXmlType);

            // Add CORS Handler
            GlobalConfiguration.Configuration.MessageHandlers.Add(new CorsHandler());
        }
    }
}

Half of the job is done. We now need to touch base with our controller and service class constructors to utilize the instances already created for them at application load.

Setup Controller

We have already set up Unity in our application. There are various methods in which we can inject a dependency, like constructor injection, and property injection, via a service locator. I am here using Constructor Injection because I find it the best method to use with Unity Container to resolve dependency.

Just go to your ProductController, and you find your constructor written as.

/// <summary>
/// Public constructor to initialize product service instance
/// </summary>
public ProductController()
{
    _productServices = new ProductServices();
}

Just add a parameter to your constructor that takes your ProductServices reference, as we did in the following.

/// <summary>  
/// Public constructor to initialize product service instance  
/// </summary>  
public ProductController(IProductServices productServices)  
{  
    _productServices = productServices;  
}  

And initialize your “productServices” variable with the parameter. In this case, when the constructor of the controller is called, it will be served with a pre-instantiated service instance and does not need to create an instance of the service, our Unity container did the job of object creation.

Setup Services

For services too, we proceed in a similar fashion. Just open your ProductServices class, we see the dependency of UnitOfWork here as in the following.

/// <summary>
/// Public constructor.
/// </summary>
public ProductServices()
{
    _unitOfWork = new UnitOfWork();
}

Again, we perform the same steps and a parameter of type UnitOfWork to our constructor.

Our code becomes

/// <summary>
/// Public constructor.
/// </summary>
public ProductServices(UnitOfWork unitOfWork)
{
    _unitOfWork = unitOfWork;
}  

Here we'll also get the pre-instantiated object on UnitOfWork. So the service does not need to worry about creating objects. Remember, we did .RegisterType<UnitOfWork>() in the Bootstrapper class.

We have now made our components independent.

Components

Image source: http://4.bp.blogspot.com/-q-o5SXbf3jw/T0ZUv0vDafI/AAAAAAAAAY4/_O8PgPNXIKQ/s320/h1.jpg

Running the application

Our job is nearly done. We need to run the application. Just hit F5. To our surprise, we'll end up with in an error page as in the following.

Run the application

Do you remember? We added a test client to our project to test our API in my first article. That test client has a controller too, we need to override its settings to make our application work. Just go to Areas -> HelpPage -> Controllers -> HelpController in the WebAPI project as in the following:

 HelpPage

Comment out the existing constructors and add a Configuration property like shown below.

// Remove constructors and existing Configuration property.
   
// public HelpController()
//     : this(GlobalConfiguration.Configuration)
// {
// }

// public HelpController(HttpConfiguration config)
// {
//     Configuration = config;
// }

// public HttpConfiguration Configuration { get; private set; }

/// <summary>
/// Add new Configuration Property
/// </summary>
protected static HttpConfiguration Configuration
{
    get { return GlobalConfiguration.Configuration; }
}

Our controller code becomes.

using System;
using System.Web.Http;
using System.Web.Mvc;
using WebApi.Areas.HelpPage.Models;

namespace WebApi.Areas.HelpPage.Controllers
{
    /// <summary>
    /// The controller that will handle requests for the help page.
    /// </summary>
    public class HelpController : Controller
    {
        // Remove constructors and existing Configuration property.

        // public HelpController()
        //     : this(GlobalConfiguration.Configuration)
        // {
        // }

        // public HelpController(HttpConfiguration config)
        // {
        //     Configuration = config;
        // }

        // public HttpConfiguration Configuration { get; private set; }

        /// <summary>
        /// Add new Configuration Property
        /// </summary>
        protected static HttpConfiguration Configuration
        {
            get { return GlobalConfiguration.Configuration; }
        }

        public ActionResult Index()
        {
            return View(Configuration.Services.GetApiExplorer().ApiDescriptions);
        }

        public ActionResult Api(string apiId)
        {
            if (!String.IsNullOrEmpty(apiId))
            {
                HelpPageApiModel apiModel = Configuration.GetHelpPageApiModel(apiId);
                if (apiModel != null)
                {
                    return View(apiModel);
                }
            }

            return View("Error");
        }
    }
}

Just run the application, we get.

Application

We already have our test client added, but for new readers, I am just again explaining how to add a test client to our API project.

Just go to Manage Nuget Packages by right-clicking the WebAPI project and type WebAPITestClient into the searchbox in online packages as in the following.

 Nuget Packages

You'll get “A simple Test Client for ASP.NET Web API”, just add it. You'll get a help controller in Areas -> HelpPage as shown below.

 ASP.NET

I have already provided the database scripts and data in my previous article, you can use that.

Append “/help” in the application URL and you'll get the test client as in the following.

 URL

You can test each service by clicking on it.

Service for GetAllProduct.

GetAllProduct

To create a new product.

 New product

In the database, we get a new product as in the following.

 Database

Update product.

Update product

We get the following in the database.

Record

Delete product.

Delete product

In the database.

Record deleted

Job done.

Job done

Image source http://codeopinion.com/wp-content/uploads/2015/02/injection.jpg

Design Flaws

What if I say there are still flaws in this design, the design is still not loosely coupled?

Do you remember what we decided when writing our first application?

Our API talks to services and services talk to the DataModel. We'll never allow the DataModel to talk to the APIs for security reasons. But did you notice that when we were registering the type in the Bootstrapper class, we also registered the type of UnitOfWork? That means we added the DataModel as a reference to our API project. This is a design problem. We tried to resolve the dependency of a dependency by violating our design and compromising security.

In my next article, we'll overcome this situation, we'll try to resolve the dependency and its dependency without violating our design and compromising security. In fact, we'll make it more secure and loosely coupled.

In my next article, we'll make use of the Managed Extensibility Framework (MEF) to do that.

Conclusion

We now know how to use Unity container to resolve a dependency and perform Inversion of Control.

But still, there are some flaws in this design. In my next article, I'll try to make the system stronger. Until then Happy Coding. You can also download the source code from GitHub. Add the required packages, if they are missing in the source code.

Read more

For more technical articles you can reach out to CodeTeddy

My other series of articles.


Similar Articles