![](/img/trans.png)
[英]'No service for type 'Identity.UserManager`1[ProjectName.ApplicationUser]' has been registered.able when container is destroy)'
[英]No service for type Identity.UserManager when using multiple identity users
我的設置
目前,我有兩個繼承自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 { }
ApplicationUser
包含共享屬性,例如名字和姓氏。 StudentUser
和EmployeeUser
都有自己的屬性和關系。 此結構遵循Table Per Hierarchy (TPH)繼承。
理想情況下,我想遵循Table Per Type (TPT)繼承,因為 SQL 結構更好。 ASP.NET Core 本身只支持 TPH,所以這就是我遵循 TPT 方法的原因。
問題
我在Startup.cs
添加了 Identity 服務:
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
當我調用UserManager<StudentUser>
或UserManager<EmployeeUser>
,出現以下錯誤:
沒有注冊“Microsoft.AspNetCore.Identity.UserManager`1[ClassroomMonitor.Models.StudentUser]”類型的服務。
我的問題
不幸的是,我無法找到有關此錯誤與此實現相結合的太多信息。
是否(甚至)有可能讓它以這種方式工作?
歡迎任何幫助或想法。
更新 1
手動添加StudentUser
或EmployeeUser
作為范圍服務似乎不起作用(作為第一個答案提到)。
services.AddScoped<UserManager<ApplicationUser>, UserManager<ApplicationUser>>();
// or..
services.AddScoped<UserManager<ApplicationUser>>();
這會引發以下錯誤:
InvalidOperationException:無法解析“Microsoft.AspNetCore.Identity.IUserStore1[ClassroomMonitor.Models.StudentUser]”類型的服務
更新 2
這是一個要點,可以讓您更好地了解項目結構:
理想情況下,您將為派生用戶類型調用與基本用戶類型相同的身份設置。
不幸的是, AddIdentity
方法包含一些防止多次使用它的代碼。
相反,您可以使用AddIdentityCore
。 角色服務已經由AddIdentity
注冊,唯一的區別是AddIdentityCore
注冊UserClaimsPrincipalFactory<TUser>
,所以為了匹配AddIdentity
設置,它需要通過AddClaimsPrincipalFactory
方法替換為UserClaimsPrincipalFactory<TUser, TRole>
。
代碼看起來像這樣:
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();
當然,您可以在自定義擴展方法中移動公共部分。
更新:雖然已配置的角色服務,你還需要調用AddRoles
以正確設置Role
的財產IndentityBuilder
,然后使用由AddEntityFrameworkStores
。
在新項目上測試:
dotnet new mvc --auth 個人
啟動.cshtml
services.AddDefaultIdentity<User>()
.AddEntityFrameworkStores<ApplicationDbContext>();
用戶.cs
public class User : IdentityUser
{
public string Test { get; set; }
}
可能這是你的問題:
_LoginPartial.cshtml
@inject SignInManager<User> SignInManager
@inject UserManager<User> UserManager
也這樣測試:
啟動文件
services.AddDefaultIdentity<User2>()
.AddEntityFrameworkStores<ApplicationDbContext>();
用戶.cs
public class User : IdentityUser
{
public string TestA { get; set; }
}
public class User2 : User
{
public string TestB { get; set; }
}
_LoginPartial.cshtml
@inject SignInManager<User2> SignInManager
@inject UserManager<User2> UserManager
您缺少它的注冊 DI。
services.AddScoped<UserManager<AppUser>, UserManager<AppUser>>()
StudentUser 和 EmployeeUser 類似
你不能為不同的用戶類型添加范圍,你真的不應該有很多從 IdentityUser 派生的不同類型,因為這意味着你要么在整個地方使用不正確的類型,要么在數據庫中使用多個不同的用戶表。
您應該真正構建您的數據,以便它有一個ApplicationUser
,它被員工實體(一個單獨的實體)或 Student 實體(又一個單獨的實體)引用。 這里有更多的設計問題而不是代碼問題。
當您AddIdentity<ApplicationUser, IdentityRole>
,ASPIdentity 將注入Usermanager<ApplicationUser>
,因此添加更多用戶管理器將無法按預期工作。
答案是您必須為每種類型的用戶創建不同的實體,1 個用於學生,1 個用於員工等。這些都將具有用戶 ID 的外鍵,這將使您能夠添加多種類型的用戶,而無需每個用戶類型不同的表。
然后,當您addIdentity
您可以注冊ApplicationUser
(目前如此),然后注入UserManager<ApplicationUser>
這將獲取用戶類型。
如果核心>=3.0
services.AddIdentity<IdentityUser, IdentityRole>()
.AddEntityFrameworkStores<WorldContext>();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.