0
votes

Before marking this as a duplicate, please take the time to read through the question!

I have created a new web app project in VS2015, added MVC 5 and Web Api 2.

I've added the following packages to the project:

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

And that created a NinjectWeb.cs and NinjectWebCommon.cs file in the App_Start folder. With breakpoints in both, I know they get hit on start up.

But I still get the

No parameterless constructor defined for this object

error when hitting a MVC controller and the

Make sure that the controller has a parameterless public constructor.

error when hitting a Web Api controller.

So I have a work-around that "solves" the problem, I've added these 2 lines to the CreateKernel method of the NinjectWebCommon.cs file:

GlobalConfiguration.Configuration.DependencyResolver = new Ninject.Web.WebApi.NinjectDependencyResolver(kernel);
System.Web.Mvc.DependencyResolver.SetResolver(new Ninject.Web.Mvc.NinjectDependencyResolver(kernel));

So the question: Where in the Ninject code should this have been handled? I would like to grap the code off GitHub to sort this out for good, but would like some hint as to where I should look?

Edit: the content of the RegisterServices method:

private static void RegisterServices(IKernel kernel) {

            // Identity
            kernel.Bind<IUserStore<ApplicationUser>>()
                .To<UserStore<ApplicationUser>>()
                .WithConstructorArgument("connectionNameOrUrl", "User.MongoDB");
            kernel.Bind<UserManager<ApplicationUser>>()
                .ToSelf()
                .InRequestScope()
                .WithConstructorArgument("store", ctx => ctx.Kernel.Get<IUserStore<ApplicationUser>>());

            // Services

            // Other
            kernel
                .Bind<IAzureSettings>()
                .To<UserAzureSettings>()
                .InRequestScope();

            // Providers
            kernel
                .Bind<WebApiUserProvider>()
                .ToSelf();
            kernel
                .Bind<MVCUserProvider>()
                .ToSelf();
            kernel
                .Bind<IUserProvider>()
                .ToMethod((ctx) => {
                    if (HttpContext.Current.Handler.GetType().Namespace.StartsWith("System.Web.Mvc")) {
                        return ctx.Kernel.Get<MVCUserProvider>(new Ninject.Parameters.IParameter[] { });
                    }
                    else {
                        return ctx.Kernel.Get<WebApiUserProvider>(new Ninject.Parameters.IParameter[] { });
                    }
                })
                .InRequestScope();
        }
1
But why should wiring the dependency resolver be part of the Ninject code?Darin Dimitrov
If it isn't it should be part of the code in the NinjectWebCommon class, but it's not. And if you browse through a couple of the question on SO, it should be obvious that it is.Steen Tøttrup
an error is itself showing, your controller is not registered.gaurav bhavsar
@gauravbhavsar That isn't what the error is indicating at all. The issue is that the configuration is required at all in order to get it Ninject to inject values into MVC and WebAPI controllersLuke
@SteenTøttrup show the code of your NinjectWebCommon, the RegisterServices() methodPedro Benevides

1 Answers

0
votes

I just did some experimentation with Ninject and MVC. I happen to have the exact two lines that you mentioned in your question in my live website, but I haven't had chance to really think about why they were required until now, other than that I needed it to inject into WebAPI.

I created a brand new ASP.NET MVC project in Visual Studio, installed the Nuget package Ninject.MVC5. I added a simple interface, concrete implementation and added a binding to the RegisterServices() method of the NinjectWebCommon class.

After adding the binding to an MVC controller, it just worked, the interface was resolved in my constructor to the concrete class. It seems that the MVC version of Ninject works straight 'out of the box', so to speak, without having to explicitly assign the Dependency injector.

I looked at the Github for Ninject.Web.WebApi and there is a sample project on the main page that you can download that has three sample applications of injection into WebAPI. The sample WebAPI example in the solution (not the OwinHosted or SelfHosted projects) also doesn't have the assignment of DependencyResolver... I ran it after restoring the Nuget packages on it and it works.

I realise this doesn't answer the question completely, but I think that a closer look at the example WebApi projects might reveal the answer. Either that, or the problem comes about because ASP.NET MVC and WebAPI exist in the same project and we want to inject into both?