Why this violates the constraint of type parameter 'TUser'?

I faced this issue, i found this: "When you are customizing ASP.NET Core Identity, you should not use AddEntityFrameworkStores anymore." you should implement yours:

public class ApplicationRoleManager:  RoleManager<Role>
public class ApplicationRoleStore :  RoleStore<Role, ApplicationDbContext, int, UserRole, RoleClaim>
public class ApplicationSignInManager :  SignInManager<User>
public class ApplicationUserManager : UserManager<User>
public class ApplicationUserStore : UserStore<User, Role, ApplicationDbContext, int, UserClaim, UserRole, UserLogin, UserToken, RoleClaim>

And Then redirect built-in services to your custom services (Startup.cs):

services.AddScoped<UserStore<User, Role, ApplicationDbContext, int, UserClaim, UserRole, UserLogin, UserToken, RoleClaim>, ApplicationUserStore> ();
services.AddScoped<UserManager<User>, ApplicationUserManager>();
services.AddScoped<RoleManager<Role>, ApplicationRoleManager>();
services.AddScoped<SignInManager<User>, ApplicationSignInManager>();
services.AddScoped<RoleStore<Role, ApplicationDbContext, int, UserRole, RoleClaim>, ApplicationRoleStore>();
services.AddScoped<IEmailSender, AuthMessageSender>();
services.AddScoped<ISmsSender, AuthMessageSender>();

Then introduce your custom services:

services.AddIdentity<User, Role>(identityOptions =>
{
 // ...
 }).AddUserStore<ApplicationUserStore>()
   .AddUserManager<ApplicationUserManager>()
   .AddRoleStore<ApplicationRoleStore>()
   .AddRoleManager<ApplicationRoleManager>()
   .AddSignInManager<ApplicationSignInManager>()
   // You **cannot** use .AddEntityFrameworkStores() when you customize everything
   //.AddEntityFrameworkStores<ApplicationDbContext, int>()
   .AddDefaultTokenProviders();

The problem is here RoleClaim must be of type IdentityRoleClaim<TKey>

 where TRole : IdentityRole<TKey, TUserRole, IdentityRoleClaim<TKey>>

instead of TRoleClaim

where TRole : IdentityRole<TKey, TUserRole, TRoleClaim>

It's reported here as a bug.


  • According to MSDN, the constraint for UserStore<TUser> is TUser : IdentityUser.
  • Also according to MSDN, IdentityUser : IdentityUser<string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>.
  • According to your declarations, User : IdentityUser<string, UserClaim, UserRole, UserLogin>.

The long names make it easy to miss, so let's alias IdentityUser as D and IdentityUser<string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim> as B. Now the above can be restated as:

  • TUser : D (a TUser must be a kind of D)
  • D : B (D is a kind of B)
  • User : B (your User is a kind of B in general but not a kind of D specifically, as required)