Я получаю это предупреждение в моем ASP. NET Core 2.2 приложении
предупреждение: Microsoft.EntityFrameworkCore.Infrastructure [10402] Более двадцати экземпляров IServiceProvider было создано для внутреннее использование Entity Framework. Обычно это вызвано внедрением нового экземпляра одноэлементной службы в каждый экземпляр DbContext. Например, вызывая UseLoggerFactory, каждый раз передавая новый экземпляр - см. https://go.microsoft.com/fwlink/?linkid=869049 для получения дополнительной информации. Подумайте о проверке вызовов в DbContextOptionsBuilder, которые могут потребовать создания новых поставщиков услуг.
Потратив некоторое время, я выяснил, что происходит в startup.cs. Я использую IdentityServer3 + OpenIDCnnection для аутентификации.
После успешного входа пользователя клиентское приложение авторизует пользователя, убедившись, что пользователь существует в базе данных клиентского приложения.
Startup.cs клиентского приложения
public clas Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IAccountService, AccountService>();
services.AddDbContext<Data.Entities.MyDBContext>(options =>
{
options.UseSqlServer(configuration.GetConnectionString("DefaultConnection"),
sqlServerOptions => sqlServerOptions.CommandTimeout(sqlCommandTimeout));
});
services.AddAuthentication(options =>
{
// removed for brevity purpose
})
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
{
// removed for brevity purpose
})
.AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
options.Events = new OpenIdConnectEvents()
{
OnTokenValidated = async context =>
{
Data.Entities.UserAccount userAccount = null;
using (var serviceProvider = services.BuildServiceProvider())
{
using (var serviceScope = serviceProvider.CreateScope())
{
using (var accountService = serviceScope.ServiceProvider.GetService<IAccountService>())
{
userAccount = await accountService.Authorize(userName);
}
}
}
if (userAccount == null)
{
throw new UnauthorizedAccessException(string.Format("Could not find user for login '{0}' ", userName));
}
},
};
});
}
}
Служба учетных записей
public class AccountService : IAccountService
{
private bool _disposed = false;
private readonly MyDBContext_dbContext;
public AccountService(MyDBContext dbContext)
{
_dbContext = dbContext;
}
public UserAccount Authorize(string userName)
{
// Ensures user exists in the database
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (_disposed)
return;
if (disposing)
{
if (_dbContext != null)
{
_dbContext.Dispose();
}
// Free any other managed objects here.
}
// Free any unmanaged objects here.
_disposed = true;
}
}
AccountService.Authorize(userName)
будет вызываться для каждого успешного входа в систему. И так на 21-м успешном пользователе и далее я начинаю видеть предупреждение.
Вопросы
1> В событии OnTokenValidated
я создаю поставщика услуг и немедленно избавляюсь от него. Почему EF все еще регистрирует предупреждение?
2> Как мне избавиться от этого предупреждения?
Я получаю это предупреждение, даже если я создаю 20+ DBContext, используя область действия
NET Fiddle DEMO