Search code examples
asp.net-coreentity-framework-coreasp.net-identityblazorblazor-server-side

Using Identity with AddDbContextFactory in Blazor


In my Blazor, .Net Core 3.1 server side app, I recently changed the EF contect scoping from transient to using a factory extension and it works well. However, I added the same dbcontext factory code to a second project that uses Identity & I get Exceptions on startup.

InvalidOperationException: Unable to resolve service for type 'OMS.DALInterfaces.Models.OmsDbContext' while attempting to activate 'Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore`9

This worked fine when no factory class was in use (ie let DI handle the OMSDbContext)

services.AddDbContext<OmsDbContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")),
            ServiceLifetime.Transient
            );
            
services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
         .AddRoles<IdentityRole>()
         .AddEntityFrameworkStores<OmsDbContext>();

Now in the project using Identity I tried:

services.AddDbContextFactory<OmsDbContext>(opt =>
                opt.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))
                .EnableSensitiveDataLogging());

services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
                .AddRoles<IdentityRole>()
                .AddEntityFrameworkStores<OmsDbContext>();

So how do you define Identity in startup when using the Factory extension?


Solution

  • Craig, got it figured out for us.

    In ConfigureServices, AddScoped of the DbContext and use the provider to get the factory from the services. Then, return the instance to the provider, as follows. The specs for Identity use scoped so I use scoped here.

            services.AddDbContextFactory<ApplicationDbContext>(options =>
            {
                options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"));
                options.EnableSensitiveDataLogging();
            });
    
            services.AddScoped<ApplicationDbContext>(p => p.GetRequiredService<IDbContextFactory<ApplicationDbContext>>().CreateDbContext());