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?