2016-12-30 1 views
1

1) Je crée une application ASP.NET MVC et je veux utiliser DbContext directement dans l'application elle-même, avec quelques services simples qui ressemblent légèrement à une architecture en couches.Ninject ne peut pas résoudre une dépendance pour un contrôleur, mais n'a aucun problème avec les services

Donc, je suis l'enregistrement de la dépendance dans la norme NinjectWebCommon bootstrapper:

kernel 
    .Bind<IDbContextFactory<WebDbContext>>() 
    .To<WebDbContextFactory>() 
    .InRequestScope() 
    .WithPropertyValue(nameof(WebDbContextFactory.ConnectionString), ConfigurationManager.ConnectionStrings["WebDb"].ConnectionString); 

Il fonctionne comme prévu, si elle initialise une classe MyService avec la dépendance IDbContextFactory<WebDbContext> dans son constructeur. En débogage, je vois une instance initialisée.

Cependant, si MyController a un constructeur avec la même dépendance, Ninject lève une exception selon laquelle la dépendance n'est pas enregistrée.

Hm, pourquoi?

2) Et l'initialisation du noyau suit:

var kernel = new StandardKernel(); 
    try 
    { 
     kernel.Bind<Func<IKernel>>().ToMethod(ctx =>() => new Bootstrapper().Kernel); 
     kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>(); 

     RegisterServices(kernel); 

     ControllerBuilder.Current.SetControllerFactory(new ControllerFactory(kernel)); 
     DependencyResolver.SetResolver(new AppDependencyResolver(kernel)); 

     return kernel; 
    } 
... 

méthode RegisterServices() contient que l'enregistrement de dépendance, donc je suppose a déjà le noyau lorsqu'il est passé à l'usine de contrôleur, par exemple.

3) Et encore une chose. La fabrique de contexte de base de données n'est pas la seule dépendance que tire MyController lors de l'initialisation. Il y a un couple comme:

kernel.Bind<MyService>().ToSelf().InRequestScope(); 

Donc, si je contourner la dépendance IDbContextFactory dans MyController, il n'a aucun problème avec les autres dépendances.

4) Et une autre chose. La solution possible est de modifier l'enregistrement de l'usine de contexte de DB à ceci:

kernel 
    .Bind<IDbContextFactory<WebDbContext>, WebDbContextFactory>() 
    .To<WebDbContextFactory>() 
    .InRequestScope() 
    .WithPropertyValue(nameof(WebDbContextFactory.ConnectionString), ConfigurationManager.ConnectionStrings["WebDb"].ConnectionString); 

Notez la deuxième méthode de type à Bind(). Avec les changements correspondants dans le constructeur MyController, bien sûr. Mais WebDbContextFactory est en fait WebDbContextFactory : IDbContextFactory<WebDbContext>. La seule façon différente est, je pense, que c'est dans mon assemblée locale (un autre projet référencé, cependant) et IDbContextFactory<> est externe. Huh?

Répondre

0

MVC a 2 points d'extension pour l'enregistrement MVC pour résoudre des services par injection de dépendance:

  • ControllerBuilder.Current.SetControllerFactory
  • DependencyResolver.SetResolver

Vous devez utiliser l'un ou l'autre pas les deux pour résoudre les services pour vos contrôleurs. Quel que soit votre problème, il est certain que vous vous trouvez dans l'une ou l'autre de ces classes, mais vous n'avez pas publié le code pour que personne ne puisse vous dire exactement ce qui ne va pas.