Friday 3 February 2012

Issue - No parameterless constructor defined for this object using Ninject in MVC3

A recent issue that got me puzzled for a small while recently was this on the yellow screen of death...

Server Error in '/' Application.
No parameterless constructor defined for this object.

In the stack trace were the following key lines
[MissingMethodException: No parameterless constructor defined for this object.]

and

[InvalidOperationException: An error occurred when trying to create a controller of type 'JasonpDoherty.Controllers.TestController'. Make sure that the controller has a parameterless public constructor.]


This confused me at first as I hadn't made any changes to any constructors during this piece of work so why had it started to complain about this now? What was even more confusing was the fact every other controller could be constructed except for this one.

I have been using Ninject for my sites and I love it. It's pretty lightweight but at the same time gives you a solid dependency injection solution for MVC3. There are tonnes of tutorials to get you going once you have downloaded the package from Nuget.

The problem is that the whole point of using Ninject in my MVC projects is so I can inject dependencies into my controllers? So why am I being told that my controller need a parameterless constructor?

After applying a bit of hindsight I realised what had happened...

My controller constructor is made up like this



I have just created another service that IStockService depends on called IReservationService. This is injected into the IStockService via the constructor. I don't need to inject a concrete version manually because Ninject will do this for me.

And the problem lies here, I actually forgot to tell Ninject to bind IReservationService to anything concrete in my Global.asax, and because I forgot to do this, Ninject did not know how to create an instance of IReservationService, and therefore could not create an instance of IStockService which in turn could not create me an instance of my controller. So instead it tries to find a default constructor in the controller of which I don't have (or want) one.

The problem isn't always that obvious because you could be working way down at another level well away from your UI/Controller and yet the exception you see indicates something is wrong with the way you have created your controller. So it's something to watch out for.

I guess the fix is to create concrete versions of your Interfaces you intend to inject with Ninject, and bind these to your interfaces in your Global.asax straight after, even if they are stubbed ones whilst you are progressing through your work.

Let me know if you have any comments or queries.

Thanks
Jason

No comments: