Unable to resolve service for type 'Microsoft.AspNetCore.Identity.UserManager` while attempting to activate 'AuthController'

141,312

Solution 1

You need to use the same user data model in SignInManager, UserManager and services.AddIdentity. Same principal is true if you are using your own custom application role model class.

So, change

services.AddIdentity<IdentityUser, IdentityRole>(options =>
    {
        options.User.RequireUniqueEmail = false;
    })
    .AddEntityFrameworkStores<Providers.Database.EFProvider.DataContext>()
    .AddDefaultTokenProviders();

to

services.AddIdentity<Automobile.Models.Account, IdentityRole>(options =>
    {
        options.User.RequireUniqueEmail = false;
    })
    .AddEntityFrameworkStores<Providers.Database.EFProvider.DataContext>()
    .AddDefaultTokenProviders();

Solution 2

Just to be clear about the answer:

If you use the class ApplicationUser in startup.cs: services.AddIdentity<ApplicationUser, IdentityRole>()

then you must use the same class in your controller when injecting it:

public AccountController(UserManager<ApplicationUser> userManager)

If you use some other class such as:

public AccountController(UserManager<IdentityUser> userManager)

then you will get this error:

InvalidOperationException: Unable to resolve service for type 'Microsoft.AspNetCore.Identity.UserManager`1[IdentityUser]'

because you used ApplicationUser in startup, not IdentityUser so this type is not registered with the injection system.

Solution 3

This is a bit unrelated to the original post but since Google brings you here... if you are getting this error and are using:

services.AddIdentityCore<YourAppUser>()

Then you will need to manually register the stuff that AddIdentity does, which can be found here: https://github.com/aspnet/Identity/blob/feedcb5c53444f716ef5121d3add56e11c7b71e5/src/Identity/IdentityServiceCollectionExtensions.cs#L79

        services.AddHttpContextAccessor();
        // Identity services
        services.TryAddScoped<IUserValidator<TUser>, UserValidator<TUser>>();
        services.TryAddScoped<IPasswordValidator<TUser>, PasswordValidator<TUser>>();
        services.TryAddScoped<IPasswordHasher<TUser>, PasswordHasher<TUser>>();
        services.TryAddScoped<ILookupNormalizer, UpperInvariantLookupNormalizer>();
        services.TryAddScoped<IRoleValidator<TRole>, RoleValidator<TRole>>();
        // No interface for the error describer so we can add errors without rev'ing the interface
        services.TryAddScoped<IdentityErrorDescriber>();
        services.TryAddScoped<ISecurityStampValidator, SecurityStampValidator<TUser>>();
        services.TryAddScoped<ITwoFactorSecurityStampValidator, TwoFactorSecurityStampValidator<TUser>>();
        services.TryAddScoped<IUserClaimsPrincipalFactory<TUser>, UserClaimsPrincipalFactory<TUser, TRole>>();
        services.TryAddScoped<UserManager<TUser>>();
        services.TryAddScoped<SignInManager<TUser>>();
        services.TryAddScoped<RoleManager<TRole>>();

You'll need to replace TUser and TRole with your implementations of those, or the default IdentityUser, IdentityRole

Solution 4

You can set IdentityUser and IdentityRole in ConfigureServices inside Startup class individually as shown below:

services.AddDefaultIdentity<IdentityUser>()
    .AddRoles<IdentityRole>()
    .AddEntityFrameworkStores<ApplicationDbContext>();

OR

you can configure directly into AddIdentity:

services.AddIdentity<IdentityUser, IdentityRole>()
        .AddEntityFrameworkStores<ApplicationDbContext>();

Solution 5

don't forget to add role manager in ConfigureServices

services.AddDefaultIdentity<IdentityUser>()
    .AddRoles<IdentityRole>() // <--------
    .AddDefaultUI(UIFramework.Bootstrap4)
    .AddEntityFrameworkStores<ApplicationDbContext>();
Share:
141,312
OMID
Author by

OMID

I work with lovely little team. we create and deploy web applications for all organizations.

Updated on July 09, 2022

Comments

  • OMID
    OMID almost 2 years

    I'm getting this error in Login Controller.

    InvalidOperationException: Unable to resolve service for type 'Microsoft.AspNetCore.Identity.UserManager`1[Automobile.Models.Account]' while attempting to activate 'Automobile.Server.Controllers.AuthController'.

    here is Auth Controller constructor:

    private SignInManager<Automobile.Models.Account> _signManager;
        private UserManager<Automobile.Models.Account> _userManager;
    
        public AuthController(UserManager<Models.Account> userManager,
                              SignInManager<Automobile.Models.Account> signManager)
        {
            this._userManager = userManager;
            this._signManager = signManager;
        }
    

    and here is ConfigureServices in startup.cs:

    public void ConfigureServices(IServiceCollection services)
        {
            // Add framework services.
            services.AddApplicationInsightsTelemetry(Configuration);
            services.Configure<AppConfig>(Configuration.GetSection("AppSettings"));
    
            //var provider = HttpContext.ApplicationServices;
            //var someService = provider.GetService(typeof(ISomeService));
    
    
            services.AddDbContext<Providers.Database.EFProvider.DataContext>(options => options
                .UseSqlServer(Configuration.GetConnectionString("DefaultConnection"),
                     b => b.MigrationsAssembly("Automobile.Server")
                ));
    
    
            services.AddIdentity<IdentityUser, IdentityRole>(options =>
            {
                options.User.RequireUniqueEmail = false;
            })
            .AddEntityFrameworkStores<Providers.Database.EFProvider.DataContext>()
            .AddDefaultTokenProviders(); 
            //services.AddScoped<SignInManager<Automobile.Models.Account>, SignInManager<Automobile.Models.Account>>();
            //services.AddScoped<UserManager<Automobile.Models.Account>, UserManager<Automobile.Models.Account>>();
    
            services.AddMvc();
            App.Service = services.BuildServiceProvider();
    
            // Adds a default in-memory implementation of IDistributedCache.
            services.AddDistributedMemoryCache();
    
            services.AddSession(options =>
            {
                // Set a short timeout for easy testing.
                options.IdleTimeout = TimeSpan.FromSeconds(10);
                options.CookieHttpOnly = true;
            });
    
        }
    
    • Federico Dipuma
      Federico Dipuma almost 7 years
      It seems to me that you are registering IdentityUser as basic user class but then you are using Automobile.Models.Account, which, of course, is not registered anywhere by ASP.NET Identity
    • OMID
      OMID almost 7 years
      @FedericoDipuma Thank you so much :) Solved.
    • Rafael
      Rafael almost 7 years
      How did you solved it.. ?
    • OMID
      OMID over 6 years
      @Lobato in services.AddIdentity just replace IdentityUser with your Identity User class
    • Naila Akbar
      Naila Akbar over 6 years
      @OMID why don't you post your comment as answer, this saved me but after some serious headache of RnD..
  • devC
    devC over 6 years
    I have the similar problem, I have my customer user and role defined in the AddIdentity method and I'm still getting the same error. Any idea why? I could post my code in a separate thread.
  • devC
    devC over 6 years
    Actually, I resolved that issue, but now facing a problem with creating the DB connection. I'll post the problem.
  • devC
    devC over 6 years
  • HojjatK
    HojjatK over 6 years
    seems your connection string has been not set correctly, check out my answer in your post.
  • Johan Herstad
    Johan Herstad almost 6 years
    This counts for all references, so if you implement the new Razor identity for asp.net core 2.1 to replace your old identitysystem, you need to replace their automatic implementation of stuff like SignInManager<IdentityUser> to SignInManager<ApplicationUser> wherever it is used. This can be annoying. Also you need to re-route from normal /Account/Login to /Identity/Account/Login etc. just some tips to help ;)
  • Cleptus
    Cleptus about 4 years
    With a code only answer, OP and others will hardly learn about the problem, consider editing your answer and adding an explanation
  • perustaja
    perustaja almost 4 years
    Had to create a custom SignInManager and this fixed it, if you plan on doing so check github.com/dotnet/docs/issues/14828
  • Aaron
    Aaron over 3 years
    I originally started down this route but found the solution here (stackoverflow.com/a/60752194/1146862) more straight forward; The only change I had to make (after re-ordering AddIdentity and AddJwtBearer was to set all three options shown in the example; I'd only been using DefaultAuthenticationScheme. I still get the cookie back on login, but [Authorize] now works for the JWT tokens without specifying an AuthenticationSchema.
  • MorganR
    MorganR over 3 years
    This is exactly what I was missing. Adding TryAddScoped<UserManager<TUser>>(); and services.TryAddScoped<SignInManager<TUser>>(); to my Startup.cs fixed my issue.