已创建超过二十个'IServiceProvider'实例供实体框架内部使用

问题描述 投票:0回答:1

我在我的ASP.NET Core 2.2应用程序中收到此警告

警告:Microsoft.EntityFrameworkCore.Infrastructure [10402]已经创建了二十多个“ IServiceProvider”实例供实体框架内部使用。这通常是由在每个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

entity-framework-core ef-core-2.0 ef-core-2.2 ef-core-2.1
1个回答
0
投票

((1)可以代替Add dbcontext,而可以定义AddDbContext方法的ServiceLifetime参数。

© www.soinside.com 2019 - 2024. All rights reserved.