在Blazor中将Identity与AddDbContextFactory一起使用



在我的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

当没有使用工厂类时(即让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>();

现在在使用Identity的项目中,我尝试了:

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的Scoped,并使用提供程序从服务中获取工厂。然后,将实例返回给提供程序,如下所示。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>();

另一个对我有用的选项是在添加DbContext 时使用ServiceLifetime.Transient

public void ConfigureServices(IServiceCollection services){
services
.AddDbContextFactory<ApplicationDbContext>(options =>
options.UseSqlServer(connectionString));
services
.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(connectionString),ServiceLifetime.Transient);
services
.AddDefaultIdentity<IdentityUser>(options =>
options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
}

最新更新