1
votes

I followed the instructions in this article to use Ninject for MVC 4 Web API Controller Constructor injection:

http://www.peterprovost.org/blog/2012/06/19/adding-ninject-to-web-api/

the problem that i am facing is when i call the api method i get error saying "Type 'CarController' does not have a default constructor".

i have even set break points at NinjectWebCommon.CreateKernel to see if that is being called. And that does get called when application runs.

Am i missing any thing?

by the way, i installed Ninject.Web.Common and Ninject from nuget for doing this. Here is my code:

MVC WEB API Controller:

public class CarController : ApiController
{
    private ICarService carService;

    public CarController(ICarService carService)
    {
        this.carService = carService;
    }

    [AcceptVerbs("GET")]
    public CarsResponse GetCars([FromUri] CarsRequest request)
    {         
        return this.carService.GetCars(request);
    }
}

in App_Start:

public class NinjectDependencyScope : IDependencyScope
{
    IResolutionRoot resolver;

    public NinjectDependencyScope(IResolutionRoot resolver)
    {
        this.resolver = resolver;
    }

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

        return resolver.TryGet(serviceType);
    }

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

        return resolver.GetAll(serviceType);
    }

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

        resolver = null;
    }
}


public class NinjectDependencyResolver : NinjectDependencyScope, IDependencyResolver
{
    IKernel kernel;

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

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

my NinjectWebCommon looks like this:

public static class NinjectWebCommon 
{
    private static readonly Bootstrapper bootstrapper = new Bootstrapper();

    public static void Start() 
    {
        DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
        DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
        bootstrapper.Initialize(CreateKernel);
    }

    public static void Stop()
    {
        bootstrapper.ShutDown();
    }

    private static IKernel CreateKernel()
    {
        var kernel = new StandardKernel();
        kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
        kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();

        RegisterServices(kernel);

        GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel);

        return kernel;
    }

    private static void RegisterServices(IKernel kernel)
    {
        kernel.Bind<ICarService>().To<CarService>();
    }        
}
1
You'll probably find the answer in this stackoverflow question. The question is for another container, but I think the answer is general enough for you to find what you need. - Steven
What ninject packages have you installed? Please check if you have the following three installed. Ninject, Ninject.MVC3, Ninject.Web.Common in the Nuget package manager window - Amila
Also, as you are using NinjectDependencyResolver as the name for the class, please check if you have a using statement Ninject.Web.Mvc. if so, this line GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel); is not using the dependency resolver that you've defined. instead it uses what's in that assembly - Amila
i don't think i need Ninject.MVC3 for MV4 Web API. I saw few posts that said that this does not work any more. Infact the post that i referred on the top, also mentions that. - M. Ali Iftikhar
@NitinSawant are you using WebApi or WebApi2 ... as the above discussion was for WebApi and used old manual tweaks to get ninject to work. Now with web api2 its very simple: aliiftikhar.azurewebsites.net/… - M. Ali Iftikhar

1 Answers

1
votes

I was having the same issue. I found the resolution by doing the following. I lost track of the webpage where I found the class NinjectMVCDependencyResolver.

    /// <summary>
    /// Creates the kernel that will manage your application.
    /// </summary>
    /// <returns>The created kernel.</returns>
    private static IKernel CreateKernel()
    {
        var kernel = new StandardKernel();
        kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
        kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();

        RegisterServices(kernel);
        // Install our Ninject-based IDependencyResolver into the Web API config
        GlobalConfiguration.Configuration.DependencyResolver 
            = new NinjectDependencyResolver(kernel);
        // Install into the MVC dependency resolver
        System.Web.Mvc.DependencyResolver.SetResolver(
            new NinjectMVCDependencyResolver(kernel));
        return kernel;
    }

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

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

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