Search code examples
c#.net-coredependency-injectionasp.net-core-mvcasp.net-identity

.Net Core Inject UserManager Without AddIdentity


I want to use usermanager methods without add identity to whole project.Because my application already uses an authentication that is not identity. I just want to connect db and insert user via usermanager. But when i use it like this got di error.

Builder.cs

builder.Services.AddDbContext<CustomIdentityDbContext>(opt => { opt.UseSqlServer(builder.Configuration.GetConnectionString("SomeDb")); });

builder.Services.AddScoped<UserManager<CustomIdentityUser>>();

Service and injection:

   private readonly UserManager<CustomIdentityUser> _userManager;

    public TenantController(UserManager<CustomIdentityUser> userManager)
    {
        _userManager = userManager;
    }

Solution

  • Because my application already uses an authentication that is not identity. I just want to connect db and insert user via usermanager.

    Sounds like you want a pure solution that doesn't regist Identity related Authentication Schemes

    Then let us check the source codes of AddDefaultIdentity:

    public static IdentityBuilder AddDefaultIdentity<TUser>(this IServiceCollection services, Action<IdentityOptions> configureOptions) where TUser : class
        {
            services.AddAuthentication(o =>
            {
                o.DefaultScheme = IdentityConstants.ApplicationScheme;
                o.DefaultSignInScheme = IdentityConstants.ExternalScheme;
            })
            .AddIdentityCookies(o => { });
    
            return services.AddIdentityCore<TUser>(o =>
            {
                o.Stores.MaxLengthForKeys = 128;
                configureOptions?.Invoke(o);
            })
                .AddDefaultUI()
                .AddDefaultTokenProviders();
        }
    

    You could see AddIdentityCore method is the possible solution for you

    Then Let's check the codes inside AddIdentityCore method:

    public static IdentityBuilder AddIdentityCore<TUser>(this IServiceCollection services, Action<IdentityOptions> setupAction)
            where TUser : class
        {
            // Services identity depends on
            services.AddOptions().AddLogging();
    
            // Services used by identity
            services.TryAddScoped<IUserValidator<TUser>, UserValidator<TUser>>();
            services.TryAddScoped<IPasswordValidator<TUser>, PasswordValidator<TUser>>();
            services.TryAddScoped<IPasswordHasher<TUser>, PasswordHasher<TUser>>();
            services.TryAddScoped<ILookupNormalizer, UpperInvariantLookupNormalizer>();
            services.TryAddScoped<IUserConfirmation<TUser>, DefaultUserConfirmation<TUser>>();
            // No interface for the error describer so we can add errors without rev'ing the interface
            services.TryAddScoped<IdentityErrorDescriber>();
            services.TryAddScoped<IUserClaimsPrincipalFactory<TUser>, UserClaimsPrincipalFactory<TUser>>();
            services.TryAddScoped<UserManager<TUser>>();
    
            if (setupAction != null)
            {
                services.Configure(setupAction);
            }
    
            return new IdentityBuilder(typeof(TUser), services);
        }
    

    It adds plenty of services into Identity builder,when IServiceCollection was build,it would regist required service for you,that why you got DI error when you just try withbuilder.Services.AddScoped<UserManager<CustomIdentityUser>>();

    Now,inject IAuthenticationSchemeProvider into PageModel and check the registed Authentication schemes with _authenticationSchemeProvider.GetAllSchemesAsync()

    When I try with default Identity,4 schemes were registed: enter image description here

    When I try with

    builder.Services.AddIdentityCore<AppUser>().AddEntityFrameworkStores<IdentityTestContext>();
    

    No Authentication scheme was registed and a record was created successfully in Database enter image description here