3

I have seen so many people ask this question and have tried what they accepted as answers but none of them have worked for me.

I keep getting this error when I try to use Ninject with my asp.net webapi

 { "Message": "An error has occurred.", "ExceptionMessage": "An error
 occurred when trying to create a controller of type
 'SubjectPostsController'. Make sure that the controller has a
 parameterless public constructor.", "ExceptionType":
"System.InvalidOperationException", "StackTrace": " at
System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create
(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type
controllerType)\ \ at
System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage
request)\ \ at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext ()",
"InnerException": { "Message": "An error has occurred.",
"ExceptionMessage": "Type
'Analyzer.Controllers.SubjectPostsController' does not have a default
 constructor", "ExceptionType": "System.ArgumentException",
"StackTrace": " at System.Linq.Expressions.Expression.New(Type type)\
\ at System.Web.Http.Internal.TypeActivator.Create[TBase](Type
instanceType)\ \ atSystem.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage
request, Type controllerType, Func`1& activator)\ \ at  System.Web.Http.Dispatcher.DefaultHttpControllerActivator.CreateHttpRequestMessa ge
request, HttpControllerDescriptor controllerDescriptor, Type
controllerType)" } }

My Controller:

using Analyzer.Models.ModelsForApp;
using Analyzer.Repository;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;

namespace Analyzer.Controllers
{
    public class SubjectPostsController : ApiController
    {
        private IRepository _repo;
        public SubjectPostsController(IRepository repo)
        {
            _repo = repo;
        }
        public IEnumerable<SubjectPost> Get()
        {
            var posts = _repo.GetSubjectPosts()
           .OrderByDescending(p =>p.Created).ToList();
            return posts;

        }
    }
}

The Ninject.WebCommon:

[assembly: WebActivatorEx.PreApplicationStartMethod(typeof  Analyzer.App_Start.NinjectWebCommon), "Start")]
[assembly: WebActivatorEx.ApplicationShutdownMethodAttribute(typeof (Analyzer.App_Start.NinjectWebCommon), "Stop")]

namespace Analyzer.App_Start
{
    using System;
    using System.Web;

using Microsoft.Web.Infrastructure.DynamicModuleHelper;

using Ninject;
using Ninject.Web.Common;
using Analyzer.Database;
using Analyzer.Repository;
using System.Web.Http;


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

    /// <summary>
    /// Starts the application
    /// </summary>
    public static void Start() 
    {
        DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
        DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
        bootstrapper.Initialize(CreateKernel);
    }

    /// <summary>
    /// Stops the application.
    /// </summary>
    public static void Stop()
    {
        bootstrapper.ShutDown();
    }

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

            RegisterServices(kernel);
            return kernel;
        }
        catch
        {
            kernel.Dispose();
            throw;
        }
    }

    /// <summary>
    /// Load your modules or register your services here!
    /// </summary>
    /// <param name="kernel">The kernel.</param>
    private static void RegisterServices(IKernel kernel)
    {
        kernel.Bind<ApplicationDbContext>().To<ApplicationDbContext>().InRequestScope();
        kernel.Bind<IRepository>().To<Repository>().InRequestScope();
    }        
}

}

The nuget packages I have installed are:

Ninject version 3.2.2.0
Ninject integration for WepApi2 3.2.4.0
Ninject Web Host for WebApi2 3.2.4.0
Ninject.MVC3 3.2.1.0
Ninject.Web 3.2.1.0
Ninject.Web.Common 3.2.3.0
Ninject.Web.Common.WebHost 3.2.3.0
WebApiContrib.IoC.Ninject

So far I've tried so many possibilities, The GlobalConfiguration.Configuration.DependencyResolver throws an exception when I tried that method.

So basically, I've run out of ideas. Does anyone know how to solve this?

UPDATE: I tried solving this using Unity and it worked. Although I don't know the drawbacks of using unity and the amount of support it gets(It doesn't seem to have been updated for almost a year). Researching more on unity but I am still interested in a solution using Ninject.

UPDATE 2: It also works with SimpleInjector...I'm beginning to think the problem is from Ninject. Can anyone get Ninject working with WebApi?

MRainzo
  • 3,800
  • 2
  • 16
  • 25
  • @NightOwl888 so in my WepApiConfig.Register, should I have a code snippet like "var k = new StandardKernel(); config.DependencyResolver = new NinjectDependencyResolver(k); ? – MRainzo Mar 08 '15 at 02:23
  • @NigtOwl888, I tried that and got the same exception as I did when I tried using the GlobalConfiguration..."a cyclic dependency was detected.." – MRainzo Mar 08 '15 at 02:26
  • did this question not work for you? http://stackoverflow.com/questions/21711996/mvc5-webapi2-and-ninject-parameterless-constructor-error?rq=1 – Dave Thieben Mar 09 '15 at 16:58
  • @davethieben not it didn't sadly. – MRainzo Mar 10 '15 at 02:06

1 Answers1

1

I use the following:

    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        var dependencyInjectionProvider = new DependencyInjectionProvider();

        // Set MVC depencendy resolver for asp mvc web project
        DependencyResolver.SetResolver(dependencyInjectionProvider.GetMvcDependencyResolver());

        // Set MVC depencendy resolver for asp mvc web API project
        GlobalConfiguration.Configuration.DependencyResolver = dependencyInjectionProvider.GetHttpDependencyResolver();


        WebApiConfig.Register(GlobalConfiguration.Configuration);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
    }

The DependencyInjectionProvider has two internal components:

  • HttpDependencyResolver Resolves injections on ApiControlelrs
  • MvcDependencyResolver Resolves injections on Mvc controllers

You can find the full implementation at https://gist.github.com/remojansen/d907f8e2c2c4bfb7f65e

Remo H. Jansen
  • 23,172
  • 11
  • 70
  • 93
  • Okay, I will check this out later. Right now I have my hands full with projects. Thanks a lot for your reply and I will certainly notify you if this worked or not when I do try it out – MRainzo Mar 14 '15 at 13:34
  • I never did have the time to try this out and moved on with other projects and simpleInjector. – MRainzo Apr 15 '15 at 17:46
  • Not some solution, bu I'm not using DI in API controllers, rather invoke new instance of the implementation :) – HerGiz Feb 03 '17 at 13:12