向Controller注入UserStore与UserManager时抛出异常
我希望将Razor页面/模型中的逻辑迁移至Controller以优化项目结构,现有一个继承自IdentityUser的ForumUser类。原本在Razor页面中,UserManager<ForumUser>、SignInManager及UserStore<ForumUser>均能正常工作,但迁移至Controller通过构造函数注入时,出现如下异常:
InvalidOperationException: Unable to resolve service for type 'EweForum.Infrastructure.Data.Extensions.ForumUserStore' while attempting to activate 'EweForum.Controllers.AccountController'.
即使替换为UserStore<ForumUser>或使用自定义的ForumUserStore、ForumUserManager也无法解决。已在program.cs中通过AddDefaultIdentity<ForumUser>配置了正确的用户类,并添加了自定义的UserManager和UserStore,相关代码如下:
Program.cs 代码
using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; using EweForum.Data; using EweForum.Infrastructure.Data.Models; using Microsoft.CodeAnalysis.Options; using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using EweForum.Infrastructure.Data.Extensions; var builder = WebApplication.CreateBuilder(args); var connectionString = builder.Configuration.GetConnectionString("DefaultConnection") ?? throw new InvalidOperationException("Connection string 'EweForumContextConnection' not found."); builder.Services.AddDbContext<EweForumContext>(options => options.UseSqlServer(connectionString)); builder.Services.AddDefaultIdentity<ForumUser>(options => { options.SignIn.RequireConfirmedAccount = false; options.Password.RequireDigit = false; options.Password.RequireNonAlphanumeric = false; options.Password.RequireUppercase = false; }) .AddUserManager<ForumUserManager>() .AddUserStore<ForumUserStore>() .AddEntityFrameworkStores<EweForumContext>(); // Add services to the container. builder.Services.AddControllersWithViews(); builder.Services.AddRazorPages(); var app = builder.Build(); // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Home/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthentication();; app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); endpoints.MapRazorPages(); }); app.Run();
相关类代码
public class ForumUser : IdentityUser public class AccountController : Controller { private readonly EweForumContext _context; private readonly SignInManager<ForumUser> _signInManager; private readonly ForumUserManager _userManager; private readonly ForumUserStore _userStore; private readonly Logger<RegisterModel> _logger; public AccountController(EweForumContext context, SignInManager<ForumUser> signInManager, ForumUserManager userManager, ForumUserStore userStore, Logger<RegisterModel>logger) { _context = context; _signInManager = signInManager; _userManager = userManager; _userStore = userStore; _logger = logger; } public class ForumUserManager : UserManager<ForumUser> { public ForumUserManager(IUserStore<ForumUser> store, IOptions<IdentityOptions> optionsAccessor, IPasswordHasher<ForumUser> passwordHasher, IEnumerable<IUserValidator<ForumUser>> userValidators, IEnumerable<IPasswordValidator<ForumUser>> passwordValidators, ILookupNormalizer keyNormalizer, IdentityErrorDescriber errors, IServiceProvider services, ILogger<UserManager<ForumUser>> logger) : base(store, optionsAccessor, passwordHasher, userValidators, passwordValidators, keyNormalizer, errors, services, logger) { } } public class ForumUserStore : UserStore<ForumUser> { public ForumUserStore(EweForumContext context, IdentityErrorDescriber describer = null) : base(context, describer) { } }
1. 调整服务注册顺序
AddEntityFrameworkStores会默认注册UserStore<ForumUser>,需将自定义AddUserStore<ForumUserStore>移至AddEntityFrameworkStores之后,确保自定义Store覆盖默认注册:
builder.Services.AddDefaultIdentity<ForumUser>(options => { options.SignIn.RequireConfirmedAccount = false; options.Password.RequireDigit = false; options.Password.RequireNonAlphanumeric = false; options.Password.RequireUppercase = false; }) .AddUserManager<ForumUserManager>() .AddEntityFrameworkStores<EweForumContext>() .AddUserStore<ForumUserStore>(); // 调整位置到AddEntityFrameworkStores之后
2. 显式注册自定义Store具体类型
AddUserStore仅注册IUserStore<ForumUser>接口到ForumUserStore实现,若要直接注入ForumUserStore具体类,需显式添加注册:
builder.Services.AddScoped<ForumUserStore>();
3. 修复Logger注入错误
AccountController中注入的Logger<RegisterModel>属于Razor页面模型,应替换为当前Controller对应的Logger:
private readonly ILogger<AccountController> _logger; public AccountController(EweForumContext context, SignInManager<ForumUser> signInManager, ForumUserManager userManager, ForumUserStore userStore, ILogger<AccountController> logger) { _context = context; _signInManager = signInManager; _userManager = userManager; _userStore = userStore; _logger = logger; }
4. 验证自定义Manager的依赖参数
确保ForumUserManager的构造函数参数均能被DI容器解析,当前构造函数符合UserManager基类要求,无需修改。
内容的提问来源于stack exchange,提问作者maria8829

