2017-08-23 1 views
3

Voici ma classe où les dépendances sont résoluesException dans Autofac: Aucun constructeur défini pour cet parameterless objet

namespace TestProj 
{ 
    public static class Bootstrapper 
    { 
     public static void Run() 
     { 
      SetAutofacWebAPI(); 
     } 

     private static void SetAutofacWebAPI() 
     { 
      var builder = new ContainerBuilder(); 

      builder.RegisterType<UserService>().As<IUserService>().InstancePerRequest(); 
      builder.RegisterType<Encryption>().As<IEncryption>().InstancePerRequest(); 

      DependencyResolver.SetResolver(new AutofacDependencyResolver(builder.Build())); 
     } 
    } 
} 

Dans le Global.asax, j'ai ceci: Bootstrapper.Run();


Voici ma classe UserService:

public class UserService : IUserService 
{ 
    private readonly IEncryption _Encryption; 

    public UserService(Encryption Encryption) 
    { 
     _Encryption = Encryption; 
    } 
    //Rest of the service here 
} 

la classe Encryption est similaire.


Et le contrôleur est ici:

public class UserController : Controller 
{ 
    private readonly IUserService _UserService; 
    public AccountController(UserService UserService) 
    { 
     _UserService = UserService; 
    } 

    public JsonResult GetLoginLogs(int Id) 
    { 
     var Logs = _UserService.GetLoginLogById(Id); 
     return Json(Logs, JsonRequestBehavior.AllowGet); 
    } 
    //The rest of the controller 
} 

ici est la version info:

Autofac : 3.5.2 
MVC : 4.0.40804.0 
DOTNET : 4 

Et puis, quand essayer localhost:5000/Account/GetLoginLogs/1 cette exception arrive :

Aucun constructeur sans paramètre défini pour cet objet.

Quelqu'un s'il vous plaît aider. Je suis sérieusement en difficulté!

+1

Je pense que vous confondez comment injecter explicitement dans les classes. utiliser les interfaces au lieu des classes concrètes lors de l'injection dans les classes dépendantes – Nkosi

+3

Vous avez enregistré 'UserService' comme' IUserService'. Vous avez également échoué à enregistrer vos contrôleurs MVC. – Amy

+1

Vérifiez, le [lien] (https://stackoverflow.com/questions/19925290/dependencyresolver-setresolver-not-working), sur les mêmes lignes que Amy ci-dessus –

Répondre

3

Je pense que vous confondez la façon dont vous avez enregistré les dépendances.

Mise à jour des commentaires par @Amy:

Vous avez également omis d'enregistrer vos contrôleurs MVC

// You can register controllers all at once using assembly scanning... 
builder.RegisterControllers(Assembly.GetExecutingAssembly()); 

Source: documentation

utilisent également les interfaces au lieu des classes concrètes lors de l'injection explicite dans les classes dépendantes car c'est ce que vous avez enregistré avec le conteneur.

public class UserService : IUserService { 
    private readonly IEncryption _Encryption; 

    public UserService(IEncryption Encryption) { 
     _Encryption = Encryption; 
    } 
    //Rest of the service here 
} 

public class UserController : Controller { 
    private readonly IUserService _UserService; 

    public AccountController(IUserService UserService) { 
     _UserService = UserService; 
    } 

    public JsonResult GetLoginLogs(int Id) { 
     var Logs = _UserService.GetLoginLogById(Id); 
     return Json(Logs, JsonRequestBehavior.AllowGet); 
    } 
    //The rest of the controller 
} 
+1

Cela résoudra le problème –

+0

Mais l'erreur qui apparaît est bizarre. –

+2

@PrashanthBenny Il s'agit d'une erreur standard trompeuse que le framework lance lorsqu'il ne peut pas initialiser le contrôleur. Je suis d'accord que c'est un message d'erreur bizarre. – Nkosi

1

En fait, je crois que l'exception que vous obtenez est pas trompeuse si vous obtenez plus profondément dans et analyser le message d'exception et trace de la pile. Vous trouverez exactement quel service n'a pas pu être trouvé et créé par le conteneur - dans ce cas, il serait UserService dans AccountController (et plus tard, Encryption dans UserService ainsi). L'exception avec "aucun constructeur sans paramètre trouvé" indique simplement que dans un constructeur existant avec des paramètres il y a un ou plusieurs paramètres qui ne peuvent pas être résolus par le conteneur, et, comme le constructeur sans paramètre manque, le type requis ne peut pas être créé. Cela peut également signifier que vous avez oublié d'enregistrer vos contrôleurs dans le conteneur, de sorte que l'Autofac n'a aucune idée qu'il devrait injecter des dépendances dans les contrôleurs.Pour aller plus loin - Autofac est très explicite avec les enregistrements - vous pouvez seulement injecter/résoudre ce que vous avez enregistré au démarrage de l'application. Si vous utilisez simplement builder.RegisterType<UserService>() - sans As<> vous pouvez uniquement injecter UserService directement. Mais lorsque vous ajoutez .As<>: builder.RegisterType<UserService>().As<IUserService>(), vous ne pouvez plus injecter UserService, mais IUserService. Pour garder la possibilité d'injecter UserService vous devrez utiliser AsSelf(): builder.RegisterType<UserService>().As<IUserService>().AsSelf(). Ensuite, vous pouvez injecter à la fois IUserService et UserService. Gardez à l'esprit API d'enregistrement Autofac est fluide, vous pouvez modifier autant de As<> que vous le souhaitez. Dans le monde de Dependecy Injection, nous n'aimons pas les composants couplés, donc l'injection de classes concrètes au lieu d'interfaces - comme vous l'avez fait - n'est pas recommandée - vous devez utiliser des interfaces partout où cela est possible. Vos enregistrements sont donc corrects, mais vous devez injecter IUserService au lieu de UserService et IEncryption au lieu de Encryption dans vos composants. Cela faciliterait les tests unitaires potentiels de ces composants, vous permettant de simuler facilement les dépendances.

En outre, vous devez enregistrer vos contrôleurs ainsi:

builder.RegisterControllers(Assembly.GetExecutingAssembly())‌​; 
+0

Je viens de copier le style du projet nopcommerce d'utiliser l'injection du constructeur. –

+0

Aujourd'hui est un jour d'apprentissage ... Permettez-moi de faire les changements nécessaires :) –

+0

Merci à vous ... J'ai mis en œuvre cela aussi et upvoted ... –