在 Blazor 中将身份与 AddDbContextFactory 结合使用

Using Identity with AddDbContextFactory in Blazor

在我的 Blazor .Net Core 3.1 服务器端应用程序中,我最近将 EF contect 作用域从瞬态更改为使用工厂扩展,并且效果很好。但是,我将相同的 dbcontext 工厂代码添加到第二个使用 Identity 的项目,并且在启动时出现异常。

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

当没有工厂 class 在使用时,这工作正常(即让 DI 处理 OMSDbContext)

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

现在在我尝试使用身份的项目中:

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

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

那么在使用Factory扩展时如何在启动时定义Identity呢?

Craig,帮我们弄明白了。

在 ConfigureServices 中,DbContext 的 AddScoped 并使用提供程序从服务中获取工厂。然后,return 将实例提供给提供者,如下所示。 Identity 的规范使用 scoped,所以我在这里使用 scoped。

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

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

这是因为 Identity EntityFrameworkStores 假设您的 DbContext 也可以通过依赖注入获得。

您正在做的是添加工厂,而不是添加您的 DbContext 本身。

您需要同时添加两者。

void BuildOptions(DbContextOptionsBuilder options) => options
    .UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))
    .EnableSensitiveDataLogging();

services.AddDbContext<OmsDbContext>(BuildOptions);

services.AddDbContextFactory<OmsDbContext>(BuildOptions);

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