7

On my ASP.NET Core 5.0 project, I changed

services.AddDbContext<SelfProgressDbContext>(...);

to

services.AddPooledDbContextFactory<SelfProgressDbContext>(...);

and now the application is not starting. A subset of errors I got:

Error while validating the service descriptor 'ServiceType: Microsoft.AspNetCore.Identity.UserManager1[SelfProgress.Domain.User] Lifetime: Scoped ImplementationType: Microsoft.AspNetCore.Identity.UserManager1[SelfProgress.Domain.User]': Unable to resolve service for type 'SelfProgress.Orm.SelfProgressDbContext' while attempting to activate > 'Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore9[SelfProgress.Domain.User,Microsoft.AspNetCore.Identity.IdentityRole1[System.Guid],SelfProgress.Orm.SelfProgressDbContext,System.Guid,Microsoft.AspNetCore.Identity.IdentityUserClaim1[System.Guid],Microsoft.AspNetCore.Identity.IdentityUserRole1[System.Guid],Microsoft.AspNetCore.Identity.IdentityUserLogin1[System.Guid],Microsoft.AspNetCore.Identity.IdentityUserToken1[System.Guid],Microsoft.AspNetCore.Identity.IdentityRoleClaim`1[System.Guid]]'.

Error while validating the service descriptor 'ServiceType: Microsoft.AspNetCore.Identity.ISecurityStampValidator Lifetime: Scoped ImplementationType: Microsoft.AspNetCore.Identity.SecurityStampValidator1[SelfProgress.Domain.User]': Unable to resolve service for type 'SelfProgress.Orm.SelfProgressDbContext' while attempting to activate 'Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore9[SelfProgress.Domain.User,Microsoft.AspNetCore.Identity.IdentityRole1[System.Guid],SelfProgress.Orm.SelfProgressDbContext,System.Guid,Microsoft.AspNetCore.Identity.IdentityUserClaim1[System.Guid],Microsoft.AspNetCore.Identity.IdentityUserRole1[System.Guid],Microsoft.AspNetCore.Identity.IdentityUserLogin1[System.Guid],Microsoft.AspNetCore.Identity.IdentityUserToken1[System.Guid],Microsoft.AspNetCore.Identity.IdentityRoleClaim1[System.Guid]]'.

Error while validating the service descriptor 'ServiceType: Microsoft.AspNetCore.Identity.RoleManager1[Microsoft.AspNetCore.Identity.IdentityRole1[System.Guid]] Lifetime: Scoped ImplementationType: Microsoft.AspNetCore.Identity.RoleManager1[Microsoft.AspNetCore.Identity.IdentityRole1[System.Guid]]': Unable to resolve service for type 'SelfProgress.Orm.SelfProgressDbContext' while attempting to activate 'Microsoft.AspNetCore.Identity.EntityFrameworkCore.RoleStore5[Microsoft.AspNetCore.Identity.IdentityRole1[System.Guid],SelfProgress.Orm.SelfProgressDbContext,System.Guid,Microsoft.AspNetCore.Identity.IdentityUserRole1[System.Guid],Microsoft.AspNetCore.Identity.IdentityRoleClaim1[System.Guid]]'.

It looks like the Identity EF store classes can no longer resolve the DB Context because of the new pooled DB context factory registration. Using AddPooledDbContextFactory seems you can't resolve DB context directly anymore. Instead, you should resolve the factory and then create a DB context manually.

My Identity registration:

services
    .AddIdentity<User, IdentityRole<Guid>>(...)
    .AddEntityFrameworkStores<SelfProgressDbContext>()
    .AddDefaultTokenProviders()

Is there a way to make default Identity stores resolve the DB context via its new factory?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459

1 Answers1

2

In the ConfigureServices, try to use AddScoped() method to register the DBContext and use the provider to get the factory from the services. Then, return the instance to the provider. The code like this:

        services.AddDbContextFactory<ApplicationDbContext>(options =>
        {
            options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"));
            options.EnableSensitiveDataLogging();
        });

        services.AddScoped<ApplicationDbContext>(p => p.GetRequiredService<IDbContextFactory<ApplicationDbContext>>().CreateDbContext());

The ApplicationDbContext.cs:

public class ApplicationDbContext : IdentityDbContext
{
     ...
}
Zhi Lv
  • 18,845
  • 1
  • 19
  • 30
  • You can use `services.AddDbContext(options => options.UseSqlServer(connectionString));` as well... Do you know if there is any other way? Custom IdentityBuilder extension maybe? – suchoss Apr 20 '21 at 07:06