HttpContext имеет значение null при доступе к внедренному объекту с помощью Ninject при первом запросе через async / await

1

Я получаю чрезвычайно загадочную ошибку при первом запросе моего веб-сервера по методу Task<ActionResult>. Впоследствии сервер работает нормально и никаких сбоев не происходит. Ошибка говорит:

Value cannot be null. Parameter name: httpContext

И он падает на первой строке:

 public async Task<ActionResult> Index()
    {
        var account = await Data.Of<Account>()
            .AsQueryable(a => a.Id == WebSecurity.CurrentUserId,
                "AllowedReportTypes",
                "AllowedReports.Parameters.ParameterChoices",
                "AllowedReports.ReportType",
                "AllowedBusinesses")
            .FirstOrDefaultAsync();

Где Data - это интерфейс IWorker который вводится через Ninject следующим образом:

kernel.Bind(typeof (IWorker<>))
    .To(typeof (Worker<>))
    .When(x=> HttpContext.Current == null)
    .InThreadScope();
kernel.Bind(typeof (IWorker<>))
    .To(typeof (Worker<>))
    .When(x => HttpContext.Current != null)
    .InRequestScope();

GlobalConfiguration.Configuration.DependencyResolver = 
    new NinjectDependencyResolver(kernel);

Эта проблема возникает, когда я использую действия async/wait. Когда они синхронны, эта проблема никогда не возникает.

Может ли кто-нибудь сказать мне, почему этот код сработает с моим первым запросом, а не с последующими запросами? Благодарю.

  • 0
    Можете ли вы уточнить, кто пытается получить доступ к httpContext и кто должен передавать его?
Теги:
asp.net-mvc
asynchronous
ninject

1 ответ

1
Лучший ответ

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

Ядро Ninject было открыто через библиотеку классов, на которую ссылался мой проект пользовательского интерфейса. Это означало, что я должен был сделать служебные вызовы ядру для разрешения зависимостей. Например, контроллеры унаследовали абстрактный класс, который разоблачил свойство Data, и тогда абстрактный класс будет иметь это в своем объявлении:

public IWorker<DbContext> Data { get { return Kernel.Get(typeof(IWorker<DbContext>)); } }

К сожалению, это анти-шаблон, и это означало, что Ninject не делал большой инъекции зависимостей. Мне пришлось переписать весь проект (к сожалению, я еще не закончил).

Проект пользовательского интерфейса теперь является составным корнем. Я смог сделать это быстро, Ninject.Web.Mvc к Ninject.Web.Mvc от Nuget, который после установки создал класс с именем NinjectWebCommon который загружает ядро, его привязки и устанавливает его как NinjectWebCommon определения зависимостей при запуске приложения. Жесткая часть переписывала все мои контроллеры, представления, уровень доступа к данным и функциональность бэкэнд... Ouch.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню