Подтвердить что ты не робот

Доступ к DbContext в промежуточном ПО в ASP.NET 5

Я написал свое собственное промежуточное программное обеспечение, которое я добавляю в

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    //...
    app.UseAutologin();
    app.UseMvc(routes =>
    {
       //...

Итак, это последнее промежуточное ПО, прежде чем Mvc вступает в игру.

В моем методе middleware Invoke я хочу (косвенно) получить доступ к DbContext.

 public async Task Invoke(HttpContext context)
  {
     if (string.IsNullOrEmpty(context.User.Identity.Name))
     {
        var applicationContext = _serviceProvider.GetService<ApplicationDbContext>();
        var signInManager = _serviceProvider.GetService<SignInManager<ApplicationUser>>();
        var result = await signInManager.PasswordSignInAsync(_options.UserName, _options.Password, true, false);
     }

     await _next(context);
  }

Почти каждый раз я получаю следующее исключение:

InvalidOperationException: Была сделана попытка использовать контекст пока он настроен. Невозможно использовать экземпляр DbContextвнутри OnConfiguring, поскольку он все еще настроен в этой точке.

Теперь это ясно выражено методом PasswordSignInAsync. Но как я могу гарантировать, что модель была создана, прежде чем делать такие вещи?

Возможно, я был не совсем ясен: я не хочу использовать DbContext сам - PasswordSignInAsync использует его при проверке пользователя и пароля.

4b9b3361

Ответ 1

Что делать, если вы введете ApplicationDbContext и SignInManager<ApplicationUser> с помощью метода Invoke:

public async Task Invoke(HttpContext context, ApplicationDbContext applicationContext, SignInManager<ApplicationUser> signInManager)
{
    if (string.IsNullOrEmpty(context.User.Identity.Name))
    {
        var result = await signInManager.PasswordSignInAsync(_options.UserName, _options.Password, true, false);
    }

    await _next(context);
}

Таким образом, службы будут устранены из правильной области. Я заметил, что вы на самом деле не используете ApplicationDbContext в любом месте, просто SignInManager. Вам это действительно нужно?

Ответ 2

Эта ошибка, вероятно, происходит потому, что любое промежуточное ПО действует как одноэлементное. Вы должны избегать использования переменных-членов в промежуточном программном обеспечении. Не стесняйтесь вводить в Invoke задачи, но не сохраняйте значение вставки в объект-член.

Смотрите: Сохранение экземпляра HttpContext в промежуточном программном обеспечении,    Услуги вызова в промежуточном программном обеспечении

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

    public async Task Invoke(HttpContext context, IMetaService metaService)
    {
            var middler = new Middler
            {
                Context = context,
                MetaService = metaService
            };

            DoSomething(middler);
    }