[英]Using AddPooledDbContextFactory with AspNetCore.Identity
I've got asp.net core webapi app which currently uses Microsoft.AspNetCore.Identity
and services.AddDbContext
in ConfigureServices
methods in Startup
class and everything works so far.我有 asp.net 核心 webapi 应用程序,它目前在
Startup
class 的ConfigureServices
方法中使用Microsoft.AspNetCore.Identity
和services.AddDbContext
,到目前为止一切正常。
I tried to use services.AddPooledDbContextFactory
instead of services.AddDbContext
to improve performance.我尝试使用
services.AddPooledDbContextFactory
而不是services.AddDbContext
来提高性能。 However when I try to use AddPooledDbContextFactory
I've got an error:但是,当我尝试使用
AddPooledDbContextFactory
时出现错误:
System.InvalidOperationException: Unable to resolve service for type 'hostapp.Data.DataContext' while attempting to activate 'Microsoft.AspNetCore.Identity.EntityFrameworkCore.RoleStore
5[hostapp.Models.AppRole,hostapp.Data.DataContext,System.Int32,hostapp.Models.AppUserRole,Microsoft.AspNetCore.Identity.IdentityRoleClaim
1[System.Int32]]'System.InvalidOperationException:尝试激活“Microsoft.AspNetCore.Identity.EntityFrameworkCore.RoleStore
5[hostapp.Models.AppRole,hostapp.Data.DataContext,System.Int32,hostapp.Models.AppUserRole,Microsoft.AspNetCore.Identity.IdentityRoleClaim
时无法解析类型“hostapp.Data.DataContext”的服务5[hostapp.Models.AppRole,hostapp.Data.DataContext,System.Int32,hostapp.Models.AppUserRole,Microsoft.AspNetCore.Identity.IdentityRoleClaim
1[System.Int32]]'
After seeing this error I created new webapi project which uses AddPooledDbContextFactory
without Microsoft.AspNetCore.Identity
which works fine.看到这个错误后,我创建了新的 webapi 项目,它使用
AddPooledDbContextFactory
而没有Microsoft.AspNetCore.Identity
工作正常。 So my question is:所以我的问题是:
What is the proper way of using services.AddPooledDbContextFactory
with Microsoft.AspNetCore.Identity
to avoid error above?将
services.AddPooledDbContextFactory
与Microsoft.AspNetCore.Identity
一起使用以避免上述错误的正确方法是什么?
in ProjectRoot/Startup.cs
在
ProjectRoot/Startup.cs
using System.Threading.Tasks;
using hostapp.Data;
using hostapp.GraphQL;
using hostapp.Interfaces;
using hostapp.Models;
using hostapp.Services;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace hostapp
{
public class Startup
{
// ...
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<ICookieService, CookieService>();
// EARLIER IMPLEMENTATION WHICH WORKS FINE =>
// services.AddDbContext<DataContext>(options =>
// {
// options.UseSqlServer(_config.GetConnectionString("DefaultConnection"));
// });
// CURRENT IMPLEMENTATION WHICH CAUSES AN ERROR
services.AddPooledDbContextFactory<DataContext>(options =>
{
options.UseSqlServer(_config.GetConnectionString("DefaultConnection"));
});
services.AddIdentityCore<AppUser>(opt =>
{
opt.Password.RequireNonAlphanumeric = false;
})
.AddRoles<AppRole>()
.AddRoleManager<RoleManager<AppRole>>()
.AddSignInManager<SignInManager<AppUser>>()
.AddRoleValidator<RoleValidator<AppRole>>()
.AddEntityFrameworkStores<DataContext>();
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.Cookie.Name = "app-cookie";
// options.Cookie.Expiration = TimeSpan.FromMinutes(30);
options.Events.OnRedirectToLogin = context =>
{
context.Response.StatusCode = StatusCodes.Status401Unauthorized;
return Task.CompletedTask;
};
});
services.AddAuthorization(opt =>
{
opt.AddPolicy("RequireAdminRole", policy => policy.RequireRole("Admin"));
});
services
.AddGraphQLServer()
.AddAuthorization()
.AddQueryType<Query>();
services.AddControllers();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseCors(options => options
.AllowAnyHeader()
.AllowAnyMethod()
.WithOrigins("https://localhost:4200")
.SetIsOriginAllowed(origin => true)
.AllowCredentials());
app.UseCookiePolicy(new CookiePolicyOptions
{
MinimumSameSitePolicy = SameSiteMode.Strict,
// HttpOnly = Microsoft.AspNetCore.CookiePolicy.HttpOnlyPolicy.Always,
// Secure = CookieSecurePolicy.Always
});
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapGraphQL();
});
}
}
}
in ProjectRoot/Data/DataContext.cs
在
ProjectRoot/Data/DataContext.cs
using hostapp.Models;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
namespace hostapp.Data
{
public class DataContext : IdentityDbContext<AppUser, AppRole, int,
IdentityUserClaim<int>, AppUserRole, IdentityUserLogin<int>,
IdentityRoleClaim<int>, IdentityUserToken<int>>
{
public DataContext(DbContextOptions<DataContext> options) : base(options)
{
}
public DbSet<AppUserClaim> Claims { get; set; }
public DbSet<AppUserClaimOffender> Offenders { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<AppUser>()
.HasMany(ur => ur.AppUserRoles)
.WithOne(u => u.AppUser)
.HasForeignKey(ur => ur.UserId)
.IsRequired();
builder.Entity<AppRole>()
.HasMany(ur => ur.AppUserRoles)
.WithOne(u => u.AppRole)
.HasForeignKey(ur => ur.RoleId)
.IsRequired();
}
}
}
in ProjectRoot/app.csproj
在
ProjectRoot/app.csproj
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="2.2.0"/>
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="5.0.0" NoWarn="NU1605"/>
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="5.0.0" NoWarn="NU1605"/>
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.6.3"/>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.0"/>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.0"/>
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="5.0.0"/>
<PackageReference Include="HotChocolate.AspNetCore" Version="11.1.0"/>
<PackageReference Include="HotChocolate.AspNetCore.Authorization" Version="11.1.0"/>
<PackageReference Include="HotChocolate.Data.EntityFramework" Version="11.1.0"/>
<PackageReference Include="Microsoft.AspNetCore.Cors" Version="2.2.0"/>
</ItemGroup>
</Project>
What is the proper way of using services.AddPooledDbContextFactory with Microsoft.AspNetCore.Identity to avoid error above?
将 services.AddPooledDbContextFactory 与 Microsoft.AspNetCore.Identity 一起使用以避免上述错误的正确方法是什么?
In the ConfigureServices, try to use AddScoped() method to register the DBContext and use the provider to get the factory from the services.在 ConfigureServices 中,尝试使用 AddScoped() 方法注册 DBContext 并使用提供者从服务中获取工厂。 Then, return the instance to the provider.
然后,将实例返回给提供者。 The code like this:
像这样的代码:
services.AddPooledDbContextFactory<DataContext>(options =>
{
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"));
options.EnableSensitiveDataLogging();
}, poolSize:32);
services.AddScoped<DataContext>(p => p.GetRequiredService<IDbContextFactory<DataContext>>().CreateDbContext());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.