Ninject + MVC3 n’injecte pas dans le contrôleur

J’ai utilisé l’extension NuGet Ninject MVC3 et je ne suis pas parvenu à l’injecter dans un contrôleur sur demande. Il ne semble pas s’être lié, car MVC est à la recherche du constructeur sans paramètre. Voici la trace de la stack:

[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, Ssortingng controllerName) +74 System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory) +199 System.Web.Mvc.c__DisplayClass6.b__2() +49 System.Web.Mvc.c__DisplayClassb`1.b__a() +13 System.Web.Mvc.SecurityUtil.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 

Et le contrôleur que j’essaye d’injecter (il faut une classe de base pour le 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) } 

Et la partie pertinente de mon NinjectWebCommon.cs:

  private static IKernel CreateKernel() { var kernel = new StandardKernel(); kernel.Bind<Func>().ToMethod(ctx => () => new Bootstrapper().Kernel); kernel.Bind().To(); RegisterServices(kernel); return kernel; } ///  /// Load your modules or register your services here! ///  /// The kernel. private static void RegisterServices(IKernel kernel) { INinjectModule[] modules = new INinjectModule[] { new Domain.DomainModule() }; kernel.Load(Assembly.GetExecutingAssembly()); kernel.Load(modules); kernel.Bind().ToSelf(); // *************** var t = kernel.Get(); } 

Enfin, voici DomainModule:

 public class DomainModule : NinjectModule { public override void Load() { Bind().To(); Bind().To(); } } 

Comme vous pouvez le voir dans mon NinjectWebCommon.cs à la ligne marquée d’un astérisque, j’ai essayé de construire le contrôleur explicitement comme test. Cela fonctionne parfaitement bien, avec les fournisseurs Xml..Providers correctement injectés.

Y a-t-il quelque chose que j’ai raté? Je ne connais pas suffisamment ce qui se passe sous le capot de l’extension NuGet MVC3 et je ne sais donc pas à quel point les liaisons du contrôleur échouent.

Toute indication sur ce qu’il faut regarder serait très appréciée, merci.

Donc, après un certain temps de bricolage désespéré, j’ai finalement trouvé mon problème. Je faisais référence aux DLL MVC4 (System.Web.Mvc) et je n’avais pas redirigé la liaison de l’ancienne version 3.0.0.0 vers 4.0.0.0:

         

Au moins, j’espère que c’est une solution décente.

Edit: comme suggéré ci-dessous, la ligne suivante est plus succincte:

   

À l’aide de Visual Studio et de Nuget, vous devez exécuter cette commande.

Paquet d’installation Ninject.MVC3

(remplacez le 3 en fonction de la version de MVC que vous utilisez)

Cela résoudra votre problème

Traw, existe-t-il une raison particulière pour laquelle vous utilisez des implémentations concrètes plutôt que des interfaces? Dans l’état actuel des choses, vous n’obtenez aucun bénéfice en retirant directement la classe (et je suis surpris que rien ne fonctionne). Je voudrais refactoriser et mettre tout derrière une interface, puis lier l’interface à une implémentation concrète. .

Voici un coup d’oeil rapide à quoi cela pourrait ressembler:

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

puis, lors de votre inscription aux services (ninject), vous appendiez:

 kernel.Bind().To(); 

Cela devrait vous amener un peu plus loin. En outre, var t = kernel.Get<...> ne fait rien du tout – juste au cas où vous vous demanderiez ce qui était arrivé à ‘it’.

S’amuser…