ATHER
ATHER

Reputation: 3384

Errors while using custom dependency resolver with Unity and Web API controller

I am using following class as a dependency resolver. Got reference from http://www.asp.net/web-api/overview/advanced/dependency-injection

   public class UnityWebAPIResolver : IDependencyResolver
    {
    protected IUnityContainer container;

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

    public object GetService(Type serviceType)
    {
        try
        {
            return container.Resolve(serviceType); **// This line throws error**
        }
        catch (ResolutionFailedException)
        {
            return null;
        }
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        try
        {
            return container.ResolveAll(serviceType); **// This line throws error**
        }
        catch (ResolutionFailedException)
        {
            return new List<object>();
        }
    }

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

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

In WebApiConfig class after route configuration i am configuring dependency resolver like this

config.DependencyResolver = new UnityWebAPIResolver(UnityConfig.GetContainer());

The problem is i am getting several errors like this..

InvalidOperationException - The type IHostBufferPolicySelector does not have an accessible constructor.
InvalidOperationException - The type ModelMetadataProvider does not have an accessible constructor.
InvalidOperationException - The type ITraceManager does not have an accessible constructor.
InvalidOperationException - The type ITraceWriter does not have an accessible constructor.
InvalidOperationException - The type IHttpControllerSelector does not have an accessible constructor.
InvalidOperationException - The type IAssembliesResolver does not have an accessible constructor.
InvalidOperationException - The type IHttpControllerTypeResolver does not have an accessible constructor.
InvalidOperationException - The type IHttpActionSelector does not have an accessible constructor.
InvalidOperationException - The type IActionValueBinder does not have an accessible constructor.
InvalidOperationException - The type IContentNegotiator does not have an accessible constructor.
InvalidOperationException - The type IHttpControllerActivator does not have an accessible constructor.
InvalidOperationException - The type IBodyModelValidator does not have an accessible constructor.

Even if i try to do something like this in my global.asax i am getting same errors.

GlobalConfiguration.Configuration.DependencyResolver = new UnityWebAPIResolver(UnityConfig.GetContainer());

Question : All dependencies into my API Controller seems to be injected properly, my only concern is since it cannot resolve several of above mentioned (framework specific ) types, is there any chance that it can cause the whole framework malfunction and generate random errors ?

Upvotes: 9

Views: 5767

Answers (1)

Steven
Steven

Reputation: 172646

There is no problem and your program works as expected here. What you see are first-chance exceptions thrown by the Unity's Resolve method. The exception is thrown because Unity will never return null when a service can't be resolved. IDependencyResolver.GetService implementations however should always return null if the requested service is not registered in dependency resolver implementation.

If GetService returns null, MVC will fall back on the framework's default implementation for the requested service. In most cases there is no need to override those services in the Unity container, and even when a different service is required, you can easily replace MVCs default implementation without adding it to the Unity configuration at all.

But since Unity is expected to throw this exception, that's why those methods contain a catch clause. So the exception you are experiencing is caught in that method and null is returned.

Obviously it is very annoying to have the debugger stop at those methods many times after starting the application, so the solution is to mark those methods with the [DebuggerStepThrough] attribute, to prevent the debugger from stopping in these methods.

Upvotes: 19

Related Questions