I have used the NuGet Ninject MVC3 extension and have been unable to get it to inject into a controller upon request. It doesn't seem to have bound, as MVC is looking for the paramaterless constructor. Here's the stack trace:
[MissingMethodException: No parameterless constructor defined for this object.]
System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) +0
System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache) +98
System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean skipCheckThis, Boolean fillCache) +241
System.Activator.CreateInstance(Type type, Boolean nonPublic) +69
System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +67
[InvalidOperationException: An error occurred when trying to create a controller of type 'MyApp.Presentation.Controllers.SearchController'. Make sure that the controller has a parameterless public constructor.]
System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +182
System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType) +80
System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String controllerName) +74
System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory) +199
System.Web.Mvc.<>c__DisplayClass6.<BeginProcessRequest>b__2() +49
System.Web.Mvc.<>c__DisplayClassb`1.<ProcessInApplicationTrust>b__a() +13
System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f) +7
System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action) +22
System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Func`1 func) +124
System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +98
System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +50
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +16
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8862676
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +184
And the controller i'm trying to inject into (it takes a base class at the moment):
public class SearchController : MainBaseController
{
private readonly MyApp.Domain.Tutor.TutorSearch TutorSearch;
protected static readonly log4net.ILog _log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
[Ninject.Inject]
public SearchController(MyApp.Domain.Tutor.TutorSearch tutorSearch)
{
this.TutorSearch = tutorSearch;
}
.... (no other constructors)
}
And the relevant part of my NinjectWebCommon.cs:
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
RegisterServices(kernel);
return kernel;
}
/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
INinjectModule[] modules = new INinjectModule[]
{
new Domain.DomainModule()
};
kernel.Load(Assembly.GetExecutingAssembly());
kernel.Load(modules);
kernel.Bind<MyApp.Domain.Tutor.TutorSearch>().ToSelf();
// ***************
var t = kernel.Get<MyApp.Presentation.Controllers.SearchController>();
}
Finally, here is DomainModule:
public class DomainModule : NinjectModule
{
public override void Load()
{
Bind<Data.Profile.IProfileProvider>().To<Data.Profile.XmlProfileProvider>();
Bind<Data.Subject.ISubjectProvider>().To<Data.Subject.XmlSubjectProvider>();
}
}
As you can see in my NinjectWebCommon.cs at the line marked with asterisks, I have tried constructing the controller explicitly as a test. This works perfectly fine, with the properly injected Xml..Providers.
Is there something I have missed? I don't know enough about what goes on under the hood of the NuGet MVC3 extension and so have no idea at which point the controller bindings are failing.
Any pointers on what to look at would be very much appreciated, thanks.
Traw, is there a particular reason that you're using concrete implementations rather than Interfaces.?? As it stands, you are gaining zero benefit from DI'ing the class straight in (and i'm surprised that you're getting anything to work) i would refactor and put everything behind an interface, then bind the interface to the concrete implementation.
Here's a quick shot at how that might look:
then, in your registering of the services (ninject), you'd add:
That should get you a little further. Also,
var t = kernel.Get<...>
actually does nothing at all - just in case you were wondering about what had happened to 'it'.Have fun...
So after quite a while of desperate tinkering, I finally found my problem. I was referencing the MVC4 (System.Web.Mvc) DLLs and had not redirected the binding of the older 3.0.0.0 version to 4.0.0.0:
At least, I hope that's a decent solution.
Edit: as suggested below, the following line is more succinct:
Using Visual Studio and Nuget you need to run this command
Install-Package Ninject.MVC3
(replace the 3 depending on which MVC version you are running)
This will solve your problem