没有类型'Microsoft.AspNetCore.Identity.UserManager` StudentUser的服务

Mat*_*ijs 14 c# roles entity-framework-core .net-core

我的设置

目前,我有两个继承的模型ApplicationUser,这是一种IdentityUser类型.用户类是:

public abstract class ApplicationUser : IdentityUser
{
    [PersonalData]
    public string FirstName { get; set; }

    [PersonalData]
    public string LastName { get; set; }

    [NotMapped]
    public string FullName => $"{FirstName} {LastName}";
}

public class StudentUser : ApplicationUser
{
    [PersonalData]
    [Required]
    public string StudentNumber { get; set; }

    // A user belongs to one group
    public Group Group { get; set; }
}

public class EmployeeUser : ApplicationUser { }
Run Code Online (Sandbox Code Playgroud)

ApplicationUser包含共享属性,如姓氏和名字.在StudentUserEmployeeUser两者各有自己的属性和关系.此结构遵循每个层次表(TPH)继承.

理想情况下,我想遵循Table Per Type(TPT)继承,因为SQL结构会更好..NET Core本身仅支持TPH,因此我遵循这种方法.

问题

Startup.cs我添加了身份服务:

services.AddIdentity<ApplicationUser, IdentityRole>()
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultTokenProviders();
Run Code Online (Sandbox Code Playgroud)

当我打电话UserManager<StudentUser>UserManager<EmployeeUser>,我收到以下错误:

没有为"Microsoft.AspNetCore.Identity.UserManager`1 [ClassroomMonitor.Models.StudentUser]"类型的服务注册.

我的问题

不幸的是,我在这个实现中找不到这个错误.是否(甚至)可以使它以这种方式工作?

欢迎任何帮助或想法.

更新1

手动添加StudentUserEmployeeUser作为范围服务似乎不起作用(作为第一个答案提到).

services.AddScoped<UserManager<ApplicationUser>, UserManager<ApplicationUser>>();
// or..
services.AddScoped<UserManager<ApplicationUser>>();
Run Code Online (Sandbox Code Playgroud)

这会引发以下错误:

InvalidOperationException:无法解析类型'Microsoft.AspNetCore.Identity.IUserStore1 [ClassroomMonitor.Models.StudentUser]'的服务

更新2

这是一个Gist,可以让您更好地了解项目结构:

Iva*_*oev 5

理想情况下,您将为派生用户类型调用与基本用户类型相同的身份设置。

不幸的是,AddIdentity方法包含一些阻止多次使用它的代码。

相反,您可以使用AddIdentityCore。角色服务已由进行注册AddIdentity,唯一的区别是AddIdentityCoreregister UserClaimsPrincipalFactory<TUser>,因此为了匹配AddIdentity设置,需要将其替换为UserClaimsPrincipalFactory<TUser, TRole>via AddClaimsPrincipalFactory方法。

代码看起来像这样:

services.AddIdentity<ApplicationUser, IdentityRole>()
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddDefaultTokenProviders()
    .AddDefaultUI();

services.AddIdentityCore<StudentUser>()
    .AddRoles<IdentityRole>()
    .AddClaimsPrincipalFactory<UserClaimsPrincipalFactory<StudentUser, IdentityRole>>()
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddDefaultTokenProviders()
    .AddDefaultUI();

services.AddIdentityCore<EmployeeUser>()
    .AddRoles<IdentityRole>()
    .AddClaimsPrincipalFactory<UserClaimsPrincipalFactory<EmployeeUser, IdentityRole>>()
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddDefaultTokenProviders()
    .AddDefaultUI();
Run Code Online (Sandbox Code Playgroud)

当然,您可以使用自定义扩展方法移动公共部分。

更新:尽管已经配置了角色服务,但是仍然需要调用AddRoles以便正确设置的Role属性IndentityBuilder,然后由来使用AddEntityFrameworkStores