Full source code to download.
I’ve been using ninject for a few years, but every time I use it with Web Api I hit some problem and they usually stem from not including the right nuget packages, not changing the DependencyResolver
or (once) forgetting how to make a binding!
For my future self and your reference, here is how it is done.
1. Nuget packages
Add Ninject.Web.WebApi
using nuget to your Web Api project.
That will install two other package dependencies:
Ninject
Ninject.Web.Common
To make everything work you need to add one more nuget package
Ninject.Web.Common.WebHost
This will pull down the WebActivatorEx
package and add a new class called NinjectWebCommon
to your App_Start
directory.
2. Edit NinjectWebCommon.cs
NinjectWebCommon.cs
is missing a key feature if you want to use ninject to construct the controllers, and I presume that is why you are using ninject inside a Web Api project.
In the CreateKernel()
method add the second line shown below. Now ninject will be used to resolve controller dependencies.
RegisterServices(kernel); GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel); return kernel;
You will need to add a couple of using statements too –
using System.Web.Http; using Ninject.Web.WebApi;
3. Register some services
To actually register some services we move to the RegisterServices(..)
method do some binding.
private static void RegisterServices(IKernel kernel) { kernel.Bind<ICaclulator>().To<Caclulator>(); }
4. Use it all
And here is the usage in the controller.
public class ValuesController : ApiController { private readonly ICaclulator _caclulator; public ValuesController(ICaclulator calculator) { _caclulator = calculator; } public int Get(int num1, int num2) { return _caclulator.Add(num1, num2); } }
Full source code to download.
I am getting Entry point was not found Exception. If i comment below line i am not seeing that exception
“GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel);”
Why it is happening ?
Shoot me a mail, you can find my address in the about page.
Perfect. Just what I needed. This was hard to find. I had spent a good hour trying to figure this one out on my own. Thanks.
Hi Rick,
Thanks for letting me know it helped.
Bryan
Seriously dude, i do not have words to thank you. I have spent hours to figure out why my VS 2015 MVC-WebApi would not work using Ninject. Followed your steps and there you go..worked like charm…!
Thanks
TheAqua
Very gland it helped and thanks for letting me know.
I share the same feelings with TheAqua! Thanks.
Very welcome ๐
I can’t believe I spent more than 10 hours to make this work. I have one large Solution Project which has MVC app, WebApi app, SignalR app, Business layer and DataAccess layer. I included Ninject in the MVC, WebApi and SignalR apps because even though they are in one solution, they are separate self-hosting applications.
Because I had multiple projects in the solution and they all had several mutual dependencies to each other but also to external NuGet libraries I often encountered exceptions of type “Could not load file or assembly ‘AssemblyName PublicKeyToken=null’ or one of its dependencies”. This exceptions were due to the usage of different versions from the external libraries that my modules used.
To solve this problem I decided that the easiest and cleanest way was to right click on the Solution Project and click Manage NuGet packages for solution. This way I made sure that anytime I added some Library to any of my project, that exact same library will be also added to another project from the solution if I were to need it.
BUT this was huge mistake and I needed more than 10 hours to figure out how to configure Ninject in the three modules that I needed it. I naively installed and reinstalled the Ninject packages from the NuGet Package Manager and of course those packages contained some libraries that I would need on one place but not on another.
After hours of pulling hair and reading the Stack Overflow forums I finally came across this simple blog post which solved the problem with the WebApi (I managed to configure the MVC and SignalR projects successfully).
I learned a valuable lesson today. That is, do not paste code or include libraries unless you are absolutely sure what is the reason for the existence of that code and how it should be used.
Hi Dejan,
I lost quite a few hours with Ninject and Web API too, that’s way a I wrote it down for my future self (and others).
Thanks for getting in touch.
Bryan
Well I was hoping this would have helped but your source code doesn’t include your NinjectDependencyResolver class as far as I can see, and you don’t reference it at all in this post except for the line where you set it as the resolver in NinjectWebCommon.
I’m having an issue running my API project with ninject when I have a solution with multiple startup projects (a WebAPI2 project, and an asp.net MVC5 project).
NinjectDependencyResolver is part of the Ninject.Web.WebApi namespace, this comes from the NuGet package Ninject.Web.WebApi.
I see what you are saying now, however my issue is persisting even after a complete wipe of all ninject in my API project and following through this and a couple other possible methods for setting ninject up (wiping each time I tried a different method…). None of them are working, which is super frustrating because I’ve gotten this type of setup to work previously, and the same type of setup isn’t working now.
What do you mean by wiping?
What is not working?
I have occasionally seen some problems with ninject which required me to go into the bin and obj folders and delete everything by hand – Clean in Visual Studio was not enough.
By wiping I am referring to completely uninstalling Ninject from the troublesome project. I have done so again, including the ninject stuff in the bin/obj folders, and still I am unable to instantiate a controller via ninject.
I know sometime in the last year or two the recommended approach for Ninject on the Api side of things was to not set the global resolver, I will now be looking into that again and see if the new preferred method works for me.
I introduced the dependency into home controller like this. Note its an mvc controller.
public class HomeController : Controller
{
public ActionResult Index(ICaclulator calculator)
{
ViewBag.Title = “Home Page”;
return View();
}
}
Now its not working.
Server Error in ‘/’ Application.
Cannot create an instance of an interface.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.MissingMethodException: Cannot create an instance of an interface.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Any idea why?
Got it. I should inject into ctor, not action method. Such a silly mistake.
Glad it is working for you now.
I’m writing an WebApi2 only app (without ASP.NET MVC – create new project, select empty web app + WebApi2 checkbox, then add Ninject.Web.WebApi.WebHost package, and then set up DependencyResolver as you did). When I run the application I get the following exception:
————–
An exception of type ‘Ninject.ActivationException’ occurred in Ninject.dll but was not handled in user code
Additional information: Error activating ModelValidatorProvider using binding from ModelValidatorProvider to NinjectDefaultModelValidatorProvider
A cyclical dependency was detected between the constructors of two services.
Activation path:
3) Injection of dependency ModelValidatorProvider into parameter defaultModelValidatorProviders of constructor of type DefaultModelValidatorProviders
2) Injection of dependency DefaultModelValidatorProviders into parameter defaultModelValidatorProviders of constructor of type NinjectDefaultModelValidatorProvider
1) Request for ModelValidatorProvider
Suggestions:
1) Ensure that you have not declared a dependency for ModelValidatorProvider on any implementations of the service.
2) Consider combining the services into a single one to remove the cycle.
3) Use property injection instead of constructor injection, and implement IInitializable
if you need initialization logic to be run after property values have been injected.
—————-
Any thoughts?
“A cyclical dependency was detected between the constructors of two services.” You’ll have to break that dependency, without knowing more about your code I can’t really suggest much else.
Hi, here is my github repo https://github.com/SerhatKOLCU/OMS dependency injectors doesn’t works for this project even ninject, autofac, unity. Help me please.
I don’t see any references to Ninject or any other DI in your code. I suggest downloading my sample solution and developing your code on top of it.
Thanks for the article! I’m getting this error: An error occurred when trying to create a controller of type ‘TestController’. Make sure that the controller has a parameterless public constructor., any ideas?
Hi Ralph,
Have you downloaded the solution I provided? It has a working example. Try building your code on top of it.
Bryan
You’re the man, thank you!!
No, you’re the man! ๐
Glad it helped.
Thanks for this, I’ve used Ninject 50 times, but never for an API, so I was pulling my hair out trying to figure out why it wasn’t working. You saved my weekend!
Happy to save your weekend!
Great post. Out of curiosity, why in Startup.Auth.cs are you using app.CreatePerOwinContext(ApplicationDbContext.Create) (line 26)?
Let’s say a controller or service needs the ApplicationDbContext injected, this would be injected from the OwinContext and not Ninject. Is there a reason for the mix?
Thanks, glad you liked it.
Regarding app.CreatePerOwinContext(ApplicationDbContext.Create), hmmm, no good reason. It came as part of the template in Visual Studio 2015 and I didn’t strip it out.
Take a look at https://nodogmablog.bryanhogan.net/2017/02/web-api-without-mvc/ to see how light a Web Api 2 app should be.
Pingback: Reusing Polly Policies with Dependency Injection | no dogma blog
Legend… why can’t ninject just include this shit on their own site??
From what I’ve seen Ninject is no longer being updated.
No parameterless constructor defined for this object.
Can’t create the constructor. Why? T_T
You might not have wired up Ninject correctly. I suggest downloading the sample and building on it.
Thanks, you saved my a lot of time.
๐ Glad it helped.
Thank you… !
Couldn’t believe it… It really works!
It really does!
๐ Glad it helped.
This really should be in the ninject documentation!!
I don’t think it’s being maintained.
This is great post. Thank you very much. It helped me.
You’re very welcome.
Very Helpful Post!! Thanks Dear!!
Thanks for letting me know, glad it helped you.
This really helped me. I didn’t know the part with adding dependency resolver. Thank you so much!
Glad it helped ๐
God bless you for this man!!!
Thanks
๐ thanks.
Hello Bryan.
Thank you for article, unfortunately it is doesn’t help me – I get same cycling error as at topic from -> “Wojtek says: December 29, 2016 at 3:59 am”.
I tryed to look at StackO.F. and people also get this error, but NO guarantee way to fix it (I tried few ways but No result). Please look, may be you can help?
My project – https://www.dropbox.com/s/t23h172f3164h0c/ServerPart%20-%20Ninject.7z?dl=0
Hi Ihor,
Have you tried using the code sample I provide?
Hello,
Yes, I did all as you wrote and tried your’s sample-project it’s starts and runs Ok.
But with my proj. I get this error and I cant see global difference between mine and your (in Ninject usage), but Iโm not very experience, so may be I missed something.
THANK YOU!! This works!
Glad to hear it helped.
Very helpful information. Thank you very much.
You are welcome.