1
votes

I've removed Unity and am now attempting to use Ninject in its place. For the most part it works, however I cannot get it to play nice with Web API 2.

I have a NinjectWebCommon.cs file (which I have not changed aside from adding some registrations which work fine if I resolve explicitly), which I can see is firing a Start event. However when I attempt to access a web API controller it moans about there being no public parameterless constructor.

An error has occurred.","ExceptionMessage":"An error occurred when trying to create a controller of type 'PlaceOrderController'. Make sure that the controller has a parameterless public constructor.

I have these Nuget packages installed (fresh yesterday, so all should be latest versions):

Ninject

Ninject.Extensions.Conventions

Ninject.Web.Common

Ninject.Web.Common.WebHost

Ninject.Web.WebApi

Ninject.Web.WebApi.WebHost

I'm not doing anything clever at this stage, just a web API controller with a constructor that takes a dependency implementing an interface. With Unity I had it working in minutes, but Ninject seems to be a configuration nightmare!

What additional steps have I missed?

NinjectWebCommons.cs

public static class NinjectWebCommon 
{
    static NinjectWebCommon()
    {
        Kernel = new InterceptAllModule();
    }

    private static readonly Bootstrapper bootstrapper = new Bootstrapper();

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

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

    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;
        }
    }

    private static void RegisterServices(IKernel kernel)
    {
        kernel.Bind<MyInterface>().To<MyClass>().InSingletonScope();
    }
}

Controller:

public MyController : ApiController
{
    private readonly MyInterface _myInterface;

    public MyController(MyInterface myInterface)
    {
        _myInterface = myInterface;
    }

    . . .
}
2

2 Answers

1
votes

You've not setup the DependencyResolver correctly. I tried a couple of Ninject packages which I could not get to work because of incompatible versions of Ninject and WebAPI (and MVC). This post: http://www.codeproject.com/Articles/412383/Dependency-Injection-in-asp-net-mvc-and-webapi-us describes in detail how to setup WebAPI to use Ninject as its dependency resolver.

0
votes

From the error message, I think the controller "PlaceOrderController" should have at least a public constructor accepting MyInterface as the only parameter.

Can you post the code of the controller?