Ninject + MVC3 does not enter into the controller

I used the NuGet Ninject MVC3 extension and could not load it into the controller on request. It doesn't seem to be bound, since MVC is looking for a constructor without a pair. 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 enter (it is taking the 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 corresponding 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 the 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 in the line marked with asterisks, I tried to build the controller explicitly as a test. This works fine, with Xml..Providers correctly entered.

Is there something I missed? I don’t know enough about what is happening under the hood of the NuGet MVC3 extension, and therefore has no idea at what point the controller crashes.

Any pointers to what to see would be greatly appreciated, thanks.

+12
c # asp.net-mvc-3 ninject binding
Jan 15 '13 at 17:32
source share
3 answers

So, after quite a long despair, I finally found my problem. I referenced the MVC4 DLL (System.Web.Mvc) and did not redirect the binding of the older version 3.0.0.0 to 4.0.0.0:

  <dependentAssembly> <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" /> <bindingRedirect oldVersion="1.0.0.0" newVersion="4.0.0.0" /> <bindingRedirect oldVersion="2.0.0.0" newVersion="4.0.0.0" /> <!-- The following line was missing --> <bindingRedirect oldVersion="3.0.0.0" newVersion="4.0.0.0" /> </dependentAssembly> 

At least I hope this is a worthy solution.

Edit: as suggested below, the following line is more concise:

  <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" /> 
+17
Jan 16 '13 at 8:49
source share

Using Visual Studio and Nuget, you need to run this command

Ninject.MVC3 installation package

(replace 3 depending on which version of MVC you are using)

This will solve your problem.

+5
Sep 07 '14 at 18:22
source share

Traw, there is a special reason why you use specific implementations rather than interfaces. Be that as it may, you get zero benefit from the DI'ing class right in (and I'm surprised you get anything to work), I would reorganize and put everything behind the interface, and then bind the interface to a specific implementation,

Here is a quick example of how this might look:

 // 'imagined' ISearchType interface public interface ISearchType { int Id { get; set; } string LastName { get; set; } } // 'imagined' TutorSearch concrete class public class TutorSearch : ISearchType { public int Id { get; set; } public string LastName { get; set; } } // your revised controller code private readonly ISearchType _tutorSearch; public SearchController(ISearchType searchType) { _tutorSearch = searchType; } 

then when registering services (ninject) you should add:

 kernel.Bind<ISearchType>().To<TutorSearch>(); 

This should get you a little further. In addition, var t = kernel.Get<...> actually does nothing - just in case you are interested in what happened to "this."

Good luck ...

+1
Jan 15 '13 at 18:15
source share



All Articles