Getting latest Ninject working with latest MVC 5 / Web Api 2?
Asked Answered
S

3

12

I know there are several questions a bit like this one, but as I'm unable to locate any documentation and none of the other questions have any answers that help me, here goes:

I create a new ASP.NET application (VS2013), MVC is selected, I add API. I run "update-package" in the Package Console to get updated to latest versions (MVC 5.1.2, Web Api 5.1.2).

Then I add the new Ninject.MVC5 and Ninject.Web.WebApi packages.

I add these lines to the web.config file (Ninject wants version 5.0, I have 5.1):

        <dependentAssembly>
            <assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" />
            <bindingRedirect oldVersion="1.0.0.0-5.1.0.0" newVersion="5.1.0.0" />
        </dependentAssembly>
        <dependentAssembly>
            <assemblyIdentity name="System.Web.Http.WebHost" publicKeyToken="31bf3856ad364e35" />
            <bindingRedirect oldVersion="1.0.0.0-5.1.0.0" newVersion="5.1.0.0" />
        </dependentAssembly>

In the App_start/NinjectWebCommon.cs file I add a single binding:

    private static void RegisterServices(IKernel kernel) {
        kernel.Bind<ILogger, NLogLogger>();
    }

Then I add a single ApiController, with ILogger as the single parameter in the constructor, and I add ILogger as a parameter to the constructor of the HomeController.

That should be it for testing?

Am I missing some wiring for WebApi ? Or does that happen "behind the scenes"?

Anyway, acessing the api controller gives me this error:

An error occurred when trying to create a controller of type 'TestController'. Make sure that the controller has a parameterless public constructor.

And trying the HomeController gives me this:

Object reference not set to an instance of an object.

I've tried the same thing, without updating to latest packages, same problem. I've been using Ninject for years with MVC 3 (I've also tried the Ninject.MVC3 package), and am totally clueless as to why that doesn't work. With WebApi, I was kind of expecting some call to SetResolver, but..

Any help would be appriciated!

Stringency answered 29/4, 2014 at 8:6 Comment(0)
M
10

This is not a MVC/WebApi issue

your configuration is wrong:

kernel.Bind<ILogger, NLogLogger>();

should be

kernel.Bind<ILogger>().To<NLogLogger>();
Merrow answered 1/5, 2014 at 9:12 Comment(2)
That's what happens when you work with Ninject for years, but with an abstraction in between! Thank you a lot! Just to clarify, what you meant with "Register the ILogger once for both" is that I register it once, and then it works for both MVC and WebApi? At least that what seems to have happened.Fredericksburg
@Remo Gloor: your answer has a syntax error. Please add '()' after 'kernel.Bind<ILogger>'. So the full answer code will be: 'kernel.Bind<ILogger>().To<NLogLogger>();'. I tired improving this answer, but apparently the Review guys didn't find any thing useful in correcting syntax error !!!Amalea
M
13

As mentioned by the documentation Ninject.Web.WebApi is not a standalone Nuget package. Choose the proper Ninject.Web.WebApi.* package for your application. Most likely it will by Ninject.Web.WebApi.WebHost in your case.

  1. Create empty Web application
  2. Install Ninject.MVC5
  3. Install Ninject.Web.WebApi.WebHost
  4. Update all Nuget packages
  5. Create a Mvc Controller and ApiController that take a ILogger dependency
  6. Register the ILogger once for both MVC and WebAPI
  7. Run
Merrow answered 30/4, 2014 at 16:3 Comment(2)
Thank you for the link, no idea why Google didn't find that. I've done as you wrote (and added the stuff to the web.config file as I wrote in the question, it isn't working without), still getting the same errors. When you write Register the ILogger once for BOTH, what does that mean? I fail to locate anything about wiring the WebApi part still. (My base project is here: bitbucket.org/steentottrup/mvc5webapi2ninjecttest)Fredericksburg
Thanks Remo, this answer is straight forward and worked for me while I've tried a lot of answers on google. Just for reference, for my project I'm using MVC5 & Web Api.Booboo
M
10

This is not a MVC/WebApi issue

your configuration is wrong:

kernel.Bind<ILogger, NLogLogger>();

should be

kernel.Bind<ILogger>().To<NLogLogger>();
Merrow answered 1/5, 2014 at 9:12 Comment(2)
That's what happens when you work with Ninject for years, but with an abstraction in between! Thank you a lot! Just to clarify, what you meant with "Register the ILogger once for both" is that I register it once, and then it works for both MVC and WebApi? At least that what seems to have happened.Fredericksburg
@Remo Gloor: your answer has a syntax error. Please add '()' after 'kernel.Bind<ILogger>'. So the full answer code will be: 'kernel.Bind<ILogger>().To<NLogLogger>();'. I tired improving this answer, but apparently the Review guys didn't find any thing useful in correcting syntax error !!!Amalea
P
4

For using Ninject in an project with MVC and WebApi you have to install the following packages:

-Ninject
-Ninject.MVC5
-Ninject.Web
-Ninject.Web.Common
-Ninject.Web.Common.WebHost
-Ninject.Web.WebApi
-Ninject.Web.WebApi.WebHost

These packages add the following files to App_Start folder:
NinjectWeb.cs:

[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(Smartiz.UI.NinjectWeb), "Start")]

namespace Smartiz.UI
{
    using Microsoft.Web.Infrastructure.DynamicModuleHelper;

    using Ninject.Web;

    public static class NinjectWeb 
    {
        /// <summary>
        /// Starts the application
        /// </summary>
        public static void Start() 
        {
            DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
        }
    }
}

NinjectWebCommon.cs:

using System;
using System.Web;
using Microsoft.Web.Infrastructure.DynamicModuleHelper;
using Ninject;
using Ninject.Extensions.Conventions;
using Ninject.Web.Common;
using Smartiz.ClientServices;
using Smartiz.UI;
using WebActivatorEx;

[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(NinjectWebCommon), "Start")]
[assembly: ApplicationShutdownMethod(typeof(NinjectWebCommon), "Stop")]

namespace Smartiz.UI
{
    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(q =>
            //  q.FromAssembliesMatching("Smartiz.ClientServices*")
            //  .SelectAllClasses()
            //  .InheritedFrom(typeof(BaseService))
            //  .BindDefaultInterface()
            //  .Configure(c => c.InSingletonScope()));
        }        
    }
}
Phosphoprotein answered 12/12, 2015 at 4:57 Comment(1)
Why add this line two times? DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));Mandelbaum

© 2022 - 2024 — McMap. All rights reserved.