1) Я создаю приложение ASP.NET MVC и хочу использовать DbContext
прямо в самом приложении вместе с некоторыми простыми службами, которые немного напоминают многоуровневую архитектуру.
Итак, прописываю зависимость в стандартном загрузчике NinjectWebCommon
:
kernel
.Bind<IDbContextFactory<WebDbContext>>()
.To<WebDbContextFactory>()
.InRequestScope()
.WithPropertyValue(nameof(WebDbContextFactory.ConnectionString), ConfigurationManager.ConnectionStrings["WebDb"].ConnectionString);
Он работает, как и ожидалось, если он инициализирует некоторый класс MyService
с зависимостью IDbContextFactory<WebDbContext>
в своем конструкторе. В отладке я вижу инициализированный экземпляр.
Однако, если MyController
имеет конструктор с такой же зависимостью, Ninject выдает исключение, что зависимость не зарегистрирована.
Хм, почему?
2) Инициализация ядра следующая:
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;
}
...
RegisterServices()
содержит эту регистрацию зависимости, поэтому я предполагаю, что ядро уже имеет ее, например, при передаче в фабрику контроллеров.
3) И еще одно. Фабрика контекста БД — не единственная зависимость, которую MyController
извлекает при инициализации. Есть такая пара:
kernel.Bind<MyService>().ToSelf().InRequestScope();
Поэтому, если я обойду зависимость IDbContextFactory
в MyController
, у нее не будет проблем с другими зависимостями.
4) И еще. Возможный обходной путь — изменить регистрацию фабрики контекста БД на это:
kernel
.Bind<IDbContextFactory<WebDbContext>, WebDbContextFactory>()
.To<WebDbContextFactory>()
.InRequestScope()
.WithPropertyValue(nameof(WebDbContextFactory.ConnectionString), ConfigurationManager.ConnectionStrings["WebDb"].ConnectionString);
Обратите внимание на второй тип в методе Bind()
. С соответствующими изменениями в конструкторе MyController
, разумеется. Но WebDbContextFactory
на самом деле WebDbContextFactory : IDbContextFactory<WebDbContext>
. Я думаю, что единственное отличие состоит в том, что он находится в моей локальной сборке (хотя это еще один проект, на который ссылаются), а IDbContextFactory<>
является внешним. Хм?