Web Api Start up Exceptions with IDependencyResolver implementation

Premchandra Singh picture Premchandra Singh · Jun 9, 2014 · Viewed 22.3k times · Source

I am developing a Web Api and I decided to use custom DependencyResolver. I refer this [Dependency Injection for Web API Controllers] article. Everything is working well so far in the terms of dependency injection into controllers. Code snippet of my configuration from my Owin startup class

private void RegisterIoC(HttpConfiguration config)
{
    _unityContainer = new UnityContainer();
    _unityContainer.RegisterType<IAccountService, AccountService>();
    .........
    .........
    config.DependencyResolver = new UnityResolver(_unityContainer);
}

But at the time when Api starts for the very first time some ResolutionFailedException thrown (but catched) inside the UnityResolver's GetService method. Here is the exception message

"Exception occurred while: while resolving. 
Exception is: InvalidOperationException - 
The current type, System.Web.Http.Hosting.IHostBufferPolicySelector, 
**is an interface and cannot be constructed. Are you missing a type mapping?**"

Above same exception thrown following types

System.Web.Http.Hosting.IHostBufferPolicySelector
System.Web.Http.Tracing.ITraceWriter
System.Web.Http.Metadata.ModelMetadataProvider
System.Web.Http.Tracing.ITraceManager
System.Web.Http.Dispatcher.IHttpControllerSelector
System.Web.Http.Dispatcher.IAssembliesResolver
System.Web.Http.Dispatcher.IHttpControllerTypeResolver
System.Web.Http.Controllers.IHttpActionSelector
System.Web.Http.Controllers.IActionValueBinder
System.Web.Http.Validation.IBodyModelValidator
System.Net.Http.Formatting.IContentNegotiator

I know that these ResolutionFailedException are thrown because I did not provide mappings in my unity configuration for above types.

Now here is my question :-, If I implement custom unity DependencyResolver I need to define mappings of above types and if need to define what will be their corresponding default implementation types OR is there some alternative way to implement DependencyResolver. I am really concerned even though application is running fine now, failing to resolve above type can cause serious issue later. Please help.

One final Addition:- For following types, same ResolutionFailedException thrown when I make request for any action into the my web api

System.Web.Http.Dispatcher.IHttpControllerActivator
System.Web.Http.Validation.IModelValidatorCache
System.Web.Http.Controllers.IHttpActionInvoker

Answer

James picture James · Feb 17, 2015

I was running in to the same issue using Unity with WebApi and OWIN/Katana.

The solution for me was to use the UnityDependencyResolver defined in the Unity.WebApi Nuget package instead of my own custom implementation (like @Omar Alani above)

Install-Package Unity.WebAPI

Note that the package will try and add a file named UnityConfig.cs in App_Start (the filename I used myself).

In that UnityConfig.cs file the package will add code to register the container against the GlobalConfiguration.Configuration.DependencyResolver which is not what we want with OWIN.

So instead of using:

GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);

Change to use:

config.DependencyResolver = new UnityDependencyResolver(container);

For completeness:

My UnityConfig.cs

public static class UnityConfig
{
    public static void Register(HttpConfiguration config)
    {
        var container = new UnityContainer();

        // Your mappings here

        config.DependencyResolver = new UnityDependencyResolver(container);
    }
}

My Startup.cs

[assembly: OwinStartup(typeof(UnityTest.BusinessLayer.Api.ApiStartup))]
namespace UnityTest.BusinessLayer.Api
{
    public partial class ApiStartup
    {
        public void Configuration(IAppBuilder app)
        {

            app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);

            HttpConfiguration httpConfig = new HttpConfiguration();

            UnityConfig.Register(httpConfig);

            ConfigureAuth(app); //In App_Start ->Startup.Auth

            WebApiConfig.Register(httpConfig);

            app.UseWebApi(httpConfig);
    }
  }
}