ASP.NET MVC 4 + Ninject MVC 3 = aucun constructeur sans paramètre défini pour cet objet

mise à JOUR - Merci de regarder ma réponse pour un lien et l'explication de la solution à ce problème

avant de commencer, je sais que c'est une question très courante et J'ai utilisé Ninject pendant de nombreuses lunes sans problèmes, mais maintenant il est venu et je ne peux pas trouver une solution. En outre, non, aucun des résultats sur Google et JUSQU'à présent m'ont aidé.

donc, considérez le bit de code suivant en cours d'exécution sur un prototype très, très, très simple ASP.NET MVC 4 project from Visual Studio 2012 on Windows Server 2008 R2:

public class DefaultController : Controller {
    private IGroupPrincipalRepository GroupPrincipalRepository { get; set; }

    [Inject]
    public DefaultController(
        IGroupPrincipalRepository groupPrincipalRepository) {
        this.GroupPrincipalRepository = groupPrincipalRepository;
    }
}

et voici la méthode NinjectWebCommon.cs RegisterServices :

kernel.Bind(typeof(IGroupPrincipalRepository)).ToConstructor(
    c =>
        new GroupPrincipalRepository(new PrincipalContext(ContextType.Domain, "?", "?", "?", "?"))).InSingletonScope();

maintenant, voici comment mes autres projets qui utilisent Ninject (mais sont ASP.NET MVC 3 sur .NET 4) fonctionne et pour autant que je sache, c'est ce qui est nécessaire pour que tout fonctionne. Donc, pourquoi est-ce que je me retrouve soudainement sans constructeur paramétrable défini pour cet objet. exceptions?

mise à JOUR

Voici le plein NinjectWebCommon.cs fichier:

[assembly: WebActivator.PreApplicationStartMethod(typeof(App_Start.NinjectWebCommon), "Start")]
[assembly: WebActivator.ApplicationShutdownMethodAttribute(typeof(App_Start.NinjectWebCommon), "Stop")]

namespace App_Start {
    using System;
    using System.DirectoryServices.AccountManagement;
    using System.Repositories.ActiveDirectory;
    using System.Web;
    using Microsoft.Web.Infrastructure.DynamicModuleHelper;
    using Ninject;
    using Ninject.Web.Common;

    public static class NinjectWebCommon {
        private static readonly Bootstrapper bootstrapper = new Bootstrapper();

        public static void Start() {
            DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
            DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
            bootstrapper.Initialize(CreateKernel);
        }

        public static void Stop() {
            bootstrapper.ShutDown();
        }

        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;
        }

        private static void RegisterServices(
            IKernel kernel) {
            kernel.Bind(typeof(IGroupPrincipalRepository)).ToConstructor(
                c =>
                    new GroupPrincipalRepository(new PrincipalContext(ContextType.Domain, "", "", "", ""))).InSingletonScope();
        }
    }
}

mise à JOUR - Merci de regarder ma réponse pour un lien et l'explication de la solution à ce problème

36
demandé sur Gup3rSuR4c 2012-09-07 07:51:13

17 réponses

je sais que c'est une vieille question mais il ne semble pas y avoir de vraies réponses et j'ai travaillé autour du problème donc voici ma solution:

créer une usine de contrôleur personnalisé:

public class NinjectControllerFactory : DefaultControllerFactory
{
    private IKernel ninjectKernel;
    public NinjectControllerFactory(IKernel kernel)
    {
        ninjectKernel = kernel;
    }
    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
    {
        return (controllerType == null) ? null : (IController) ninjectKernel.Get(controllerType);
    }
}

ensuite, si vous utilisez NinjectHttpApplication, ajouter la ligne suivante à OnApplicationStarted:

ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory(Kernel));

si vous n'utilisez pas NinjectHttpApplication, Ajoutez cette ligne quelque part après avoir créé votre noyau et de passer une référence à votre fraîchement créé noyau.

C'est ça.

48
répondu Jere.Jones 2012-12-25 04:36:13

Eh bien, je n'ai pas une réponse exacte pourquoi l'erreur est à venir, mais je sais qui est la cause et qui est Visual Studio 2012. J'ai installé Visual Studio 2010 sur la même machine que 2012, installé ASP.NET MVC 4 pour 2010 et j'ai recréé le projet 2012 en 2010 mot pour mot, lettre pour lettre. Le résultat final est que lorsque 2010 debugs le projet tout fonctionne bien et Ninject injecte les dépendances comme il se doit.

quand 2012 débogue son projet il vient avec l'exception No parameterless constructor defined for this object . Le re-ciblage entre .net 4.0 et .net 4.5 en 2012 ne fait rien. La réinstallation de Ninject à partir de NuGet ne fait rien non plus. J'ai même configuré les projets 2010 et 2012 pour utiliser le serveur IIS local pour être absolument sûr et le résultat final est le même.

je vais supposer qu'il y a un bug avec Visual Studio 2012 ou avec Ninject. La seule différence que j'ai entre les deux projets, il y a L'IDE d'où ils fuient et le projet 2012 est celui qui s'effondre, c'est pourquoi je pointe du doigt Visual Studio 2012.

mise à JOUR

les gars. Les gars! J'ai rencontré ce problème à nouveau, et j'ai trouvé la solution dans une autre question SO: Ninject + MVC3 n'injecte pas dans le contrôleur .

en gros, c'est ce qui manque à la Web.config qui permet de travailler:

<dependentAssembly>
    <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
    <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>

je suppose que cela oblige le cadre à être conscient des conteneurs IoC qui permet à Ninject le finalement être en mesure de se lier. Bien que, je ne peux pas m'empêcher de penser que le paquet Ninject NuGet devrait chercher l'existence de cette redirection obligatoire dans le Web.config et l'auto-magiquement l'ajouter. Il serait certainement aider avec beaucoup de cheveux tirer se passe sur cette question.

P. S.-vote de la morve de ce post, je liés, car il le mérite!

27
répondu Gup3rSuR4c 2017-05-23 11:54:21

ne réinventez pas la roue et essayez juste Install-Package Ninject.MVC3

7
répondu Juanjo 2014-07-09 13:40:53

j'ai reçu le même message d'erreur après avoir reçu le MVC3 de NuGet.

Je ne sais pas si vous avez la même configuration que moi, mais mon web.config est généré automatiquement en fonction de l'environnement. Le MVC de NuGet ajoute rows (<runtime>) au web.config et ces lignes ont été supprimées car mes fichiers de config-Fusion n'étaient pas configurés correctement.

Cordialement,

Kim

3
répondu Kim Thörning 2012-09-20 05:59:21

Voici une solution sale! Mettez ce

var type = typeof(Ninject.Web.Mvc.MvcModule);

dans le début de la AppStart événement (ou ailleurs )

laissez-moi vous expliquer ce que cela signifie Si quelqu'un n'a pas encore eu trick. La chose est notre classe d'application http pourrait résider n'importe où dans la solution. Pas seulement dans l'application web. Et c'est très important parce que asp.net la routine de compilation est différente des applications habituelles de la bibliothèque. Il charge avec impatience toutes les bibliothèques référencées par L'intermédiaire de BuildManager helper, alors que clr ne charge généralement pas les types dès le début à moins qu'ils ne soient directement utilisés.

revenons maintenant à notre situation: Ninject.Web.Mvc fonctionne comme plugin dynamique, qui ne nécessite aucune mention dans un code. Et n'est donc pas chargée si elle a été référencée à l'intérieur de la bibliothèque de classe qui mène à MVC cassé.Initialisation de la dépendance.

1
répondu wallice 2013-07-28 15:15:13

le problème semble se produire quand on utilise Visual Studio 2012/2013 avec ASP.NET 4.0 / 4.5. La version de System.Web.Mvc a été définie à 4.0.0.0 dans le fichier Web.config . Il n'a pas de travail.

ma solution était de

  1. supprimer NinjectWebCommon.cs
  2. copier la classe NinjectControllerFactory de Dere dans le projet:

    public class NinjectControllerFactory : DefaultControllerFactory
    {
       private IKernel ninjectKernel;
       public NinjectControllerFactory(IKernel kernel)
       {
          ninjectKernel = kernel;
       }
    
       protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
       {
          return (controllerType == null) ? null : (IController) ninjectKernel.Get(controllerType);
       }
    }
    
  3. modifier le contenu de Global.asax à:

    public class MvcApplication : NinjectHttpApplication
    {
       protected override IKernel CreateKernel()
       {
           IKernel kernel = new StandardKernel();
    
           // kernel.Load(Assembly.GetExecutingAssembly());
    
           // kernel.Bind<ISomeClass>().To<SomeClass>();
    
           return kernel;
       }
    
       protected override void OnApplicationStarted()
       {
           AreaRegistration.RegisterAllAreas();
    
           WebApiConfig.Register(GlobalConfiguration.Configuration);
           FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
           RouteConfig.RegisterRoutes(RouteTable.Routes);
           BundleConfig.RegisterBundles(BundleTable.Bundles);
    
           ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory(Kernel));
       }
    }
    

    après ça, vos injections devraient marcher.

1
répondu MovGP0 2014-01-09 02:55:47

tout cela est tout simplement ridicule, je suis passé à Autofac, fatigué de ne jamais être capable une seule fois D'ajouter Ninject à un projet avec succès. API Web, MVC4, MVC5 ont tous eu des problèmes.

pour les personnes MVC5, en utilisant Ninject MVC3, ajouter ce qui suit À web.niveau de l'application config:

 <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
            <dependentAssembly>
                <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35"/>
                <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0"/>
            </dependentAssembly>
            <dependentAssembly>
                <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35"/>
                <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0"/>
            </dependentAssembly>
            <dependentAssembly>
                <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35"/>
                <bindingRedirect oldVersion="1.0.0.0-5.1.0.0" newVersion="5.1.0.0"/>
            </dependentAssembly>
        </assemblyBinding>
    </runtime>
1
répondu Brian Ogden 2014-06-14 06:19:41

je me suis arraché les cheveux pendant plusieurs heures sur un projet récent que j'ai déplacé de MVC 3 à MVC 4. En l'absence de réponses précises, j'ai pensé que c'était quelque chose que j'ai fait, car il semble que le Ninject.MVC3 nuget package fonctionnera très bien avec MVC4 - et en effet il fonctionne.

dans mon cas, je ne mettais pas entièrement à niveau le projet MVC3. Après avoir suivi ce guide j'ai obtenu des choses à travailler comme prévu. Ma conjecture est que j'ai été absent un redirection de la liaison d'assemblage.

donc si vous mettez à jour un projet MVC 3 en MVC 4, en utilisant Ninject et en obtenant l'erreur définie par le constructeur sans paramétrage, espérons que cela vous aidera.

0
répondu JasonCoder 2013-06-13 13:56:47

Comme toutes les précédentes affiches ont déclaré cela m'a causé quelques poils gris. Dans mon cas, j'ai "optimisé" mes références trop. Ninject.* les choses étaient là, mais se sont détériorées. J'ai effacé toutes les références et nettoyé les paquets.conf manualli et a ajouté les paquets à nouveau-victoire!

0
répondu juhan_h 2013-07-09 10:14:55

j'ai le même problème et la seule chose qui fonctionne pour moi est de changer le" serveur Web local IIS "dans les propriétés du projet Web à"utiliser Visual Studio Development Server".

enter image description here

Je ne sais pas pourquoi mais quand je fais cela, mon point de rupture dans NinjectWebCommon est hited. Comme @Alex l'a dit, C'est quelque chose avec Visual Studio 2012 Pas assez brillant pour exécuter le code dans NinjectWebCommon chaque fois que vous construisez votre application. Il est aussi possible que je ne sois pas assez brillant pour comprendre comment ça marche sous le capot.

Je n'aime pas ma solution parce que je préférerais utiliser mon serveur Web IIS Local mais pour le moment, j'ai une application à créer et à beaucoup de temps a pris avec ce $%?!!/ bogue..caractéristique..pas sûr.

0
répondu Samuel 2014-02-23 04:00:04

cela a été résolu pour moi en ajoutant une référence via Nuget à Ninject.Web.MVC.

0
répondu hanzolo 2014-04-28 21:06:08

j'ai essayé toutes ces solutions, mais aucune n'a fonctionné.

C'est comme ça que je l'ai résolu: Supprimé tout mon intérimaire asp.net des dossiers. Après avoir fait ça, j'ai eu de nouvelles erreurs de configuration. Je les ai fixées. La dernière, et vraie erreur est sortie: new Bootstrapper () essayait de charger une version plus ancienne d'une dll ninject. Supprimé tous les paquets ninject. Installé les paquets ninject nuget un par un, assurez-vous que la bonne version est installée.

0
répondu dawidg 2014-05-16 03:48:13

J'ai essayé de mettre en place Ninject avec MVC 5. Finalement j'ai dû utiliser la solution avec controller factory d'abord, et la solution avec reliure redirect ensuite. Après que tout fonctionne comme prévu. Utilisé un serveur IIS Local.

0
répondu n0ne 2014-05-30 22:45:02

j'ai pu résoudre ce problème dans un projet web MVC5 en supprimant une directive #if #endif de mon constructeur de contrôleurs.

0
répondu James Blake 2015-12-02 21:25:35

raccourci pour tout cela: Télécharger un des Nuget Pacakges suivants:

  • Ninject.MVC3
  • Ninject.MVC5

qui prendra soin de la reliure dont vous avez besoin.

0
répondu jhilden 2016-05-25 21:57:41

j'ai réparé la mine en retirant Ninject MVC5 et en installant Ninject MVC3, de Nuget.

MVC5 == Ninject.MVC5
MVC4 == Ninject.MVC3
MVC3 == Ninject.MVC3

Vérifiez la version du système.Web.MVC dans les références pour être sûr quelle version de MVC vous êtes actuellement.

0
répondu MiloTheGreat 2017-03-29 16:14:22

j'ai eu ce problème mais seulement sur les appels de Service Web. J'ai trouvé ma solution sur cette réponse https://stackoverflow.com/a/12379938/129580 ci-dessous se trouve le code d'échantillon fourni

public class Service : WebService
{
  public IContextProvider ContextProvider {get;set;}

  public Service()
  {
    ContextProvider = DependencyResolver.Current.GetService<IContextProvider>();
  }
}

que j'ai ensuite fini par devenir, espérons que cela aide...

/// <summary>
/// Summary description for PartMarking
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
[System.Web.Script.Services.ScriptService]
public class PartMarking : System.Web.Services.WebService
{
    private readonly IUnitOfWork _unitOfWork;

    public PartMarking()
    {
        _unitOfWork = DependencyResolver.Current.GetService<IUnitOfWork>();
    }

    [WebMethod]
    public DataSet GetParentConfigurations(string engineModel, string componentCode)
    {
        var results = _unitOfWork.PartMarking.GetParentSicMarkings(engineModel, componentCode);
        return results;
    }
}
0
répondu Geovani Martinez 2018-08-08 13:34:06