Simple way to share Dependency Resolvers between MVC and Web API

I had several projects in past using ASP.NET MVC 4 and 5 and ASP.NET Web API that reside in same project. When you want to share DI container between MVC and Web API things can become complicated.

Reason for this is because ASP.NET MVC 5 uses interface System.Web.Mvc.IDependencyResolver for implementing dependency resolver and  ASP.NET Web API uses System.Web.Http.Dependencies.IDependencyResolver interface which has the same name but resides in different namespace.

These two interfaces are different, even they have a same name.

Why should you use MVC and Web API in the same project

There could be many reasons for this. For me the main reason was simplifying the way to securing Web API access by implementing session support in ASP.NET Web API even it is not recommended.

This way we can detect request coming from our MVC Application without need to protect API Key and API Secret which we use for mobile access to Web API. Protecting API Key and API Secret on web application can be very complicated.
 
If you want to learn more about ASP.NET Web API I recommend a great book that I love written by real experts:
BookWebAPIEvolvable
Designing Evolvable Web APIs with ASP.NET

Simple implementation

I am usually using Ninject as DI container of my choice. First we need to reference Ninject in our project.

After that we create class called NinjectRegistrations which inherits NinjectModule and will be used for registering types into container.

public class NinjectRegistrations : NinjectModule
    {
        public override void Load()
        {
            Bind<IApiHelper>().To<ApiHelper>();
        }
    }

 

After that we will create class NinjectDependencyResolver that will implement both required interfaces mentioned above:

 public class NinjectDependencyResolver : NinjectDependencyScope, IDependencyResolver, System.Web.Mvc.IDependencyResolver
    {
        private readonly IKernel kernel;

        public NinjectDependencyResolver(IKernel kernel)
            : base(kernel)
        {
            this.kernel = kernel;
        }

        public IDependencyScope BeginScope()
        {
            return new NinjectDependencyScope(this.kernel.BeginBlock());
        }
    }

 

 
We also need to implement class NinjectDependencyScope which is inherited from NinjectDependencyResolver:

    public class NinjectDependencyScope : IDependencyScope
    {
        private IResolutionRoot resolver;

        internal NinjectDependencyScope(IResolutionRoot resolver)
        {
            Contract.Assert(resolver != null);

            this.resolver = resolver;
        }

        public void Dispose()
        {
            var disposable = this.resolver as IDisposable;
            if (disposable != null)
            {
                disposable.Dispose();
            }

            this.resolver = null;
        }

        public object GetService(Type serviceType)
        {
            if (this.resolver == null)
            {
                throw new ObjectDisposedException("this", "This scope has already been disposed");
            }

            return this.resolver.TryGet(serviceType);
        }

        public IEnumerable<object> GetServices(Type serviceType)
        {
            if (this.resolver == null)
            {
                throw new ObjectDisposedException("this", "This scope has already been disposed");
            }

            return this.resolver.GetAll(serviceType);
        }
    }

 

That is entire implementation. Usage is very simple. To use the same container in MVC and Web API project we just create Ninject container in Global.asax.cs and pass same Ninject resolver to MVC and Web API.


NinjectModule registrations = new NinjectRegistrations();
var kernel = new StandardKernel(registrations);
var ninjectResolver = new NinjectDependencyResolver(kernel);

DependencyResolver.SetResolver(ninjectResolver); // MVC
GlobalConfiguration.Configuration.DependencyResolver = ninjectResolver; // Web API
 

You can use the same method for any kind of DI container not only Ninject.

And if you liked this post, go ahead and subscribe here to my RSS Feed to make sure you don’t miss other content like this.

 
 

9 Comments on Simple way to share Dependency Resolvers between MVC and Web API

  1. Vivekanand Swamy
    October 1, 2014 at 6:00 pm (4 years ago)

    Hi Zec,
    Perfectly working. Thank you.

    Reply
    • Radenko Zec
      October 1, 2014 at 8:15 pm (4 years ago)

      Thanks for comment Vivekanand.

      Reply
  2. Maxim V. Pavlov
    February 19, 2015 at 3:48 pm (4 years ago)

    What if I removed Global.asax and am just using a Startup.cs class to configure an application with both MVC and WebAPI? How can I configure MVC Resolver? Thank you.

    Reply
  3. Ben Smith
    May 2, 2015 at 10:21 am (3 years ago)

    Many thanks, this worked great.

    Just a quick note to anyone who has problems implementing this: In the article it states “first we need to reference Ninject in our project”. Make sure that you pull down ONLY the main Ninject package and not any of the other MVC or Web API specific packages as this will cause this approach to fail.

    Thanks again!

    Reply
    • Radenko Zec
      May 2, 2015 at 10:29 am (3 years ago)

      Thanks. Glad it help you.

      Reply
  4. Jon Wilson
    November 12, 2015 at 8:24 pm (3 years ago)

    You saved my day with this. Thank you so much! The key to getting this to work is mentioned in Ben Smith’s comment: “Make sure that you pull down ONLY the main Ninject package and not any of the other MVC or Web API specific packages as this will cause this approach to fail.”

    Reply
    • Radenko Zec
      November 12, 2015 at 9:10 pm (3 years ago)

      Thanks for comment Jon.

      Reply
  5. Phoébe Mac
    March 21, 2018 at 11:25 am (7 months ago)

    I’m confused – where should these classes go so they are accessible from both api project
    and web mvc project?

    Reply
  6. Max
    August 22, 2018 at 10:08 am (2 months ago)

    Help me, please. I can`t find solution for an issue. When i write in Application_Start() method this: “GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel)” I have an error “Cannot implicity convert type Ninject.Web.MVC.NinjectDependencyResolver to System.Web.Http.Dependencies.IDependencyResolver”.

    Reply

Leave a Reply