首页 > 解决方案 > 尝试激活登录控制器时无法解析 IdentityUserManager 类型的服务

问题描述

我正在尝试在我的 LoginController 中调用登录函数。我正在使用身份框架,但在解决依赖关系时遇到了问题。

我已经尝试将默认接口扩展到我自己的类,并且我刚刚尝试使用默认值。我认为我对注入依赖项时发生的事情没有正确的理解。

IdentityUserManager 是我的客户用户管理器,它扩展了默认的身份用户管理器。DataContext 扩展了 IdentityDBContext。

登录控制器

   [ResponseCache(NoStore = true, Location = ResponseCacheLocation.None)]
    public class LoginController : Controller
    {
        #region Private Fields

        private readonly SignInManager<IdentityUser> _signInManager;
        private readonly IdentityUserManager _identityUserManager;
        private readonly IDataContext _context;

        #endregion

        #region Constructors

        public LoginController(SignInManager<IdentityUser> signInManager, IdentityUserManager identityUserManager, IDataContext context)
        {
            this._signInManager = signInManager;
            this._identityUserManager = identityUserManager;
            this._context = context;
        }

我的 IdentityUserManager 类。IIdentityUserManager 接口除了指定我的 3 个自定义方法之外什么也不做。

  public class IdentityUserManager : UserManager<IdentityUser>, IIdentityUserManager
    {
        private readonly IDataContext _context;
        private readonly ILDAPUserManager _ldapUserManager;
        private IUserStore<IdentityUser> _userStore;

        /// <summary>
        /// Constructor for Identity User Manager
        /// </summary>
        /// <param name="context">Data context</param>
        /// <param name="userStore">Provides abstraction for store that manages user accounts</param>
        /// <param name="identityOptions">Retrieves identity options</param>
        /// <param name="passwordHasher">Abstraction for hashing passwords</param>
        public IdentityUserManager(ILDAPUserManager ldapUserManager, IDataContext context, IUserStore<IdentityUser> userStore): base(userStore, null, null, null, null, null, null, null, null)
        {
            this._ldapUserManager = ldapUserManager;
            this._context = context;
            this._userStore = userStore;
        }

从我的startup.cs

 services.AddIdentityCore<IdentityUser>(); // .AddEntityFrameworkStores<DataContext>();
            services.AddDbContext<IDataContext, DataContext>();
            services.AddScoped<ILDAPUserManager, LDAPUserManager>();
            services.AddScoped<UserManager<IdentityUser>, IdentityUserManager>();
            services.AddScoped<IUserStore<IdentityUser>, IdentityUserStore>();
            services.AddTransient<SignInManager<IdentityUser>>();
            services.AddTransient<IDbConfig, DataContextFactory>();

这是抛出的错误消息

System.InvalidOperationException: Unable to resolve service for type 'CareInTime.Service.Controllers.IdentityUserManager' while attempting to activate 'CareInTime.Service.Controllers.LoginController'.
   at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvider sp, Type type, Type requiredBy, Boolean isDefaultParameterRequired)
   at lambda_method(Closure , IServiceProvider , Object[] )
   at Microsoft.AspNetCore.Mvc.Controllers.ControllerActivatorProvider.<>c__DisplayClass4_0.<CreateActivator>b__0(ControllerContext controllerContext)
   at Microsoft.AspNetCore.Mvc.Controllers.ControllerFactoryProvider.<>c__DisplayClass5_0.<CreateControllerFactory>g__CreateController|0(ControllerContext controllerContext)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeInnerFilterAsync>d__14.MoveNext()
--- End of stack trace from previous location where exception was thrown ---

标签: c#dependency-injectionasp.net-identity

解决方案


您注册IdentityUserManagerUserManager<IdentityUser>

 services.AddScoped<UserManager<IdentityUser>, IdentityUserManager>();

UserManager<IdentityUser>这意味着容器知道解决IdentityUserManager

控制器构造函数

public LoginController(SignInManager<IdentityUser> signInManager, 
    IdentityUserManager identityUserManager, 
    IDataContext context
) { ...

明确要求,IdentityUserManager但容器不知道如何根据启动时注册的内容解析该类型。

因此,要么更新构造函数以期望在启动时注册的内容,要么添加IdentityUserManager到服务集合中

//...

services.AddScoped<IdentityUserManager>();

//...

所以可以直接注入。


推荐阅读