Language

Using the Web API Dependency Resolver

By |

This tutorial shows how to inject dependencies into your ASP.NET Web API controller, using the Web API dependency resolver.

Download the completed project.

A dependency is an object or interface that another object requires. For example, in the tutorial Creating a Web API that Supports CRUD Operations, we defined a ProductsController class that requires an IProductRepository instance. The implementation looked like this:

public class ProductsController : ApiController
{
    private static IProductRepository repository = new ProductRepository();

    // Controller methods not shown.
} 

This is not the best design, because the call to new the ProductRepository is hard-coded into the controller class. To use a different implementation of IProductRepository, we would need to change the code in ProductRepository. It is better if the ProductsController is not tied to any concrete instance of IProductRepository.

Dependency injection addresses this problem. With dependency injection, an object is not responsible for creating its own dependencies. Instead, you inject the dependency when you create the object, through a constructor parameter or a setter method.

Here is a revised implementation of ProductsController:

public class ProductsController : ApiController
{
    private readonly IProductRepository repository;

    public ProductsController(IProductRepository repository)
    {
        if (repository == null)
        {
            throw new ArgumentNullException("repository");
        }
        this.repository = repository;
    }

This is better. Now can switch to another IProductRepository instance without touching the implementation of ProductsController.

But wait — in ASP.NET Web API, you do not create the controller directly. Instead, the framework creates the controller for you, and the framework does not know anything about IProductRepository. The framework can only create your controller by calling a parameterless constructor.

This is where the dependency resolver comes in. The job of the dependency resolver is to create objects that the framework requires at run time, including controllers. By providing a custom dependency resolver, you can create controller instances on behalf of the framework.

A Simple Dependency Resolver

The following code shows a simple dependency resolver. This code is mainly just to show how dependency injection works in Web API. Later, we'll see how to incorporate an IoC container for a more general solution.

// A simple implementation of IDependencyResolver, for example purposes.
class SimpleContainer : IDependencyResolver
{
    static readonly IProductRepository respository = new ProductRepository();

    public IDependencyScope BeginScope()
    {
        // This example does not support child scopes, so we simply return 'this'.
        return this; 
    }

    public object GetService(Type serviceType)
    {
        if (serviceType == typeof(ProductsController))
        {
            return new ProductsController(respository);
        }
        else
        {
            return null;
        }
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        return new List<object>();
    }

    public void Dispose()
    {
        // When BeginScope returns 'this', the Dispose method must be a no-op.
    }
}

A dependency resolver implements the IDependencyResolver interface. The IDependencyResolver interface  inherits two other interfaces, IDependencyScope and IDisposable:

namespace System.Web.Http.Dependencies
{
    public interface IDependencyResolver : IDependencyScope, IDisposable
    {
        IDependencyScope BeginScope();
    }

    public interface IDependencyScope : IDisposable
    {
        object GetService(Type serviceType);
        IEnumerable<object> GetServices(Type serviceType);
    }
}

The IDependencyScope interface defines two methods:

  • GetService: Creates one instance of a specified type.
  • GetServices: Create a collection of objects of a specified type.

For controllers, the framework calls GetService to get a single instance of the controller. This is where our simple container creates the controller and injects the repository.

For any types that your dependency resolver does not handle, GetService should return null, and GetServices should return an empty collection object. In particular, don't throw an exception for unknown types.

The IDependencyResolver interface inherits IDependencyScope and adds one method:

  • BeginScope: Creates a nested scope.

Later, we will discuss how nested scopes are used to manage object lifetimes. For now, our implementation of BeginScope simply returns this.

Setting the Dependency Resolver

Now set the dependency resolver on the Web API global configuration object.

In Solution Explorer, double-click Global.asax. Visual Studio will open the file named Global.asax.cs file, which is the code-behind file for Global.asax. This file contains code for handling application-level and session-level events in ASP.NET.

Inside the Application_Start method, set GlobalConfiguration.Configuration.DependencyResolver to your dependency resolver:

public class WebApiApplication : System.Web.HttpApplication
{
    void ConfigureApi(HttpConfiguration config)
    {
        config.DependencyResolver = new SimpleContainer();
    }

    protected void Application_Start()
    {
        ConfigureApi(GlobalConfiguration.Configuration);

        // ...
    }
}

Scope and Object Lifetime

Controllers are created per request. To help manage object lifetimes, IDependencyResolver uses the IDisposable interface.

The dependency resolver attached to the HttpConfiguration object has global scope. When the framework creates a new instance of a controller, it calls IDependencyResolver.BeginScope. This method returns an IDependencyScope. The framework calls GetService on the IDependencyScope instance to get the controller. When the framework is done processing the request, it calls Dispose on the child scope. You can use the Dispose method to dispose of the controller’s dependencies.

Dependency Injection with IoC Containers

An IoC container is a software component that is responsible for creating dependencies. IoC containers provide a general framework for dependency injection. If you use an IoC container, then you don’t need to wire up objects directly in code. Several open-source .Net IoC containers are available, such as Autofac, Castle Windsor, Ninject, Spring.NET, StructureMap, and others.

The following example uses uses Unity, an IoC container developed by Microsoft patterns & practices.

namespace ProductStore
{
    using System;
    using System.Collections.Generic;
    using System.Web.Http;
    using System.Web.Http.Dependencies;
    using Microsoft.Practices.Unity;

    class ScopeContainer : IDependencyScope
    {
        protected IUnityContainer container;

        public ScopeContainer(IUnityContainer container)
        {
            if (container == null)
            {
                throw new ArgumentNullException("container");
            }
            this.container = container;
        }

        public object GetService(Type serviceType)
        {
            if (container.IsRegistered(serviceType))
            {
                return container.Resolve(serviceType);
            }
            else
            {
                return null;
            }
        }

        public IEnumerable<object> GetServices(Type serviceType)
        {
            if (container.IsRegistered(serviceType))
            {
                return container.ResolveAll(serviceType);
            }
            else
            {
                return new List<object>();
            }
        }

        public void Dispose()
        {
            container.Dispose();
        }
    }

    class IoCContainer : ScopeContainer, IDependencyResolver
    {
        public IoCContainer(IUnityContainer container)
            : base(container)
        {
        }

        public IDependencyScope BeginScope()
        {
            var child = container.CreateChildContainer();
            return new ScopeContainer(child);
        }
    }
}

The ScopeContainer class implements IDependencyScope and represents a child scope. The IoCContainer class implements the global-scope dependency resolver. In the BeginScope method, it creates a new ScopeContainer instance. The Unity container also has the concept of a child container, so we initialize the child ScopeContainer with a Unity child container. The ScopeContainer.Dispose method disposes of the Unity child container.

The following code registers the controller and the repository with Unity and then sets the dependency resolver:

void ConfigureApi(HttpConfiguration config)
{
    var unity = new UnityContainer();
    unity.RegisterType<ProductsController>();
    unity.RegisterType<IProductRepository, ProductRepository>(
        new HierarchicalLifetimeManager());
    config.DependencyResolver = new IoCContainer(unity);
}

Web API controllers are created per HTTP request and disposed after the request is handled. The simple in-memory repository shown in Creating a Web API that Supports CRUD Operations won't work in a real web application, because any changes to the data are immediately discarded. In the sample project for this tutorial, I modified the repository to use Entity Framework backed with a SQL Server Compact database.

Mike Wasson

By Mike Wasson, Mike Wasson is a programmer-writer at Microsoft.

Table of Contents

Getting Started with ASP.NET Web API

Creating Web APIs

Web API Clients

Web API Routing and Actions

Working with HTTP

Formats and Model Binding

OData Support in ASP.NET Web API

Security

Hosting ASP.NET Web API

Testing and Debugging

Extensibility

Resources