Ninject не может разрешить зависимость для контроллера, но не имеет проблем со службами

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<> является внешним. Хм?


person yaapelsinko    schedule 30.12.2016    source источник


Ответы (1)


MVC имеет 2 точки расширения для регистрации MVC для разрешения сервисов посредством внедрения зависимостей:

  • ControllerBuilder.Current.SetControllerFactory
  • DependencyResolver.SetResolver

Вы должны использовать один или другой не оба для разрешения служб для ваших контроллеров.

Какой бы ни была ваша точная проблема, она обязательно находится внутри одного или обоих этих классов, но вы не опубликовали код, поэтому никто не может точно сказать вам, что происходит не так.

person NightOwl888    schedule 19.01.2017