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?

4
  • @NightOwl888 so in my WepApiConfig.Register, should I have a code snippet like "var k = new StandardKernel(); config.DependencyResolver = new NinjectDependencyResolver(k); ? Commented Mar 8, 2015 at 2:23
  • @NigtOwl888, I tried that and got the same exception as I did when I tried using the GlobalConfiguration..."a cyclic dependency was detected.." Commented Mar 8, 2015 at 2:26
  • did this question not work for you? stackoverflow.com/questions/21711996/… Commented Mar 9, 2015 at 16:58
  • @davethieben not it didn't sadly. Commented Mar 10, 2015 at 2:06

1 Answer 1

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

Sign up to request clarification or add additional context in comments.

3 Comments

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
I never did have the time to try this out and moved on with other projects and simpleInjector.
Not some solution, bu I'm not using DI in API controllers, rather invoke new instance of the implementation :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.