Asp.Net Core 2.1 Identity - UserStore 依赖注入

Posted

技术标签:

【中文标题】Asp.Net Core 2.1 Identity - UserStore 依赖注入【英文标题】:Asp.Net Core 2.1 Identity - UserStore dependency injection 【发布时间】:2018-11-23 10:59:06 【问题描述】:

我正在尝试为我的身份模型实现自定义 UserStore;但是,我在应用启动时遇到了这个运行时错误:

InvalidOperationException:无法解析服务类型 '[Project].Models.Identity.ApplicationUserStore' 尝试 激活“[项目].Models.Identity.ApplicationUserManager”。

堆栈:

Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateArgumentCallSites(类型 serviceType, 类型 implementationType, CallSiteChain callSiteChain, ParameterInfo[] 参数,bool throwIfCallSiteNotFound) Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateConstructorCallSite(类型 serviceType, Type implementationType, CallSiteChain callSiteChain) Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateExact(ServiceDescriptor 描述符,类型 serviceType,CallSiteChain callSiteChain) Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateExact(类型 serviceType, CallSiteChain callSiteChain) Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateCallSite(类型 serviceType, CallSiteChain callSiteChain) Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.CreateServiceAccessor(类型 serviceType) System.Collections.Concurrent.ConcurrentDictionary.GetOrAdd(TKey key, Func valueFactory) Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(类型 serviceType, ServiceProviderEngineScope serviceProviderEngineScope) Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(类型 服务类型) Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider 提供者,类型 serviceType) Microsoft.AspNetCore.Identity.IdentityBuilder+c__DisplayClass22_0.b__0(IServiceProvider 服务) Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite、ServiceProviderEngineScope 范围) Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor.VisitCallSite(IServiceCallSite callSite,TArgument 参数) Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite、ServiceProviderEngineScope 范围) Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor.VisitCallSite(IServiceCallSite callSite,TArgument 参数) Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine+c__DisplayClass1_0.b__0(ServiceProviderEngineScope 范围) Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(类型 serviceType, ServiceProviderEngineScope serviceProviderEngineScope) Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(类型 服务类型) Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvider sp, Type type, Type requiredBy, bool isDefaultParameterRequired) lambda_method(闭包,IServiceProvider,对象[]) Microsoft.AspNetCore.Mvc.Controllers.ControllerActivatorProvider+c__DisplayClass4_0.b__0(ControllerContext 控制器上下文) Microsoft.AspNetCore.Mvc.Controllers.ControllerFactoryProvider+c__DisplayClass5_0.g__CreateController|0(ControllerContext 控制器上下文) Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(参考 State next, ref Scope scope, ref object state, ref bool isCompleted) Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync() Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter() Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext 上下文)Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(参考 State next, ref Scope scope, ref object state, ref bool isCompleted) Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync() Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync() Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext http上下文) Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext 语境) Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext 语境) Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext 上下文)

我的UserStore 实现:

public class ApplicationUserStore : IUserStore<Employee>,
                     IUserClaimStore<Employee>,
                     IUserLoginStore<Employee>,
                     IUserRoleStore<Employee>,
                     IUserPasswordStore<Employee>,
                     IUserSecurityStampStore<Employee>

    #region Constructor signatures I tried for dependency injection
    public ApplicationUserStore(ApplicationDbContext context, IdentityErrorDescriber describer = null)
    

    
    public ApplicationUserStore(ApplicationDbContext context)
    

    
    public ApplicationUserStore()
    

    
    public ApplicationUserStore(DbContext context)
    

    
    #endregion
    ...

我的UserManager 实现:

public class ApplicationUserManager : UserManager<Employee>

    public ApplicationUserManager(ApplicationUserStore store, IOptions<IdentityOptions> optionsAccessor, IPasswordHasher<Employee> passwordHasher, IEnumerable<IUserValidator<Employee>> userValidators, IEnumerable<IPasswordValidator<Employee>> passwordValidators, ILookupNormalizer keyNormalizer, IdentityErrorDescriber errors, IServiceProvider services, ILogger<UserManager<Employee>> logger)
        : base(store, optionsAccessor, passwordHasher, userValidators, passwordValidators, keyNormalizer, errors, services, logger)
    
    

我的SignInManager 实现:

public class ApplicationSignInManager : SignInManager<Employee>

    public ApplicationSignInManager(ApplicationUserManager userManager, IHttpContextAccessor contextAccessor, IUserClaimsPrincipalFactory<Employee> claimsFactory, IOptions<IdentityOptions> optionsAccessor, ILogger<SignInManager<Employee>> logger, IAuthenticationSchemeProvider schemes)
        : base(userManager, contextAccessor, claimsFactory, optionsAccessor, logger, schemes)
    
    

并且,在Startup.ConfigureServices

        ...
        services.AddIdentityCore<Employee>()
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddUserStore<ApplicationUserStore>()
            .AddUserManager<ApplicationUserManager>()
            .AddSignInManager<ApplicationSignInManager>()
            .AddDefaultTokenProviders();

        services.AddTransient<IUserStore<Employee>, ApplicationUserStore>();
        ...

我需要知道导致问题的原因、解决方法以及任何地方是否有关于 Asp.Net Core 2.1 依赖注入激活器签名的文档。

【问题讨论】:

如果你声明了 services.AddTransient, ApplicationUserStore>(),你不能在你的构造器中使用 ApplicationUserStore。您需要使用 IUserStore @hugo。不幸的是,在没有AddUserStore 的情况下使用AddTransient 对我不起作用,在没有AddTransient 的情况下使用AddUserStore 也不起作用;我一直收到同样的消息。 你注册ApplicationDbContext了吗? 不是。该行只是告诉 Identity 要使用的 IdentityDbContext 的类型。它期望它被预先配置和注册,例如services.AddDbContext&lt;ApplicationDbContext&gt;();。您的其他自定义服务可能会遇到类似问题。 投反对票的人,你能说明原因吗? 【参考方案1】:

在查看了 here 和 here 的开源实现之后,我想出了一个线索来说明问题所在 - 我猜对了。 UserStore需要通过Startup.ConfigureServices中的这一行注册:

    services.AddScoped<ApplicationUserStore>();

所以,我的最终方法是:

    ...
    services.AddIdentityCore<Employee>()
        .AddUserManager<ApplicationUserManager>()
        .AddSignInManager<ApplicationSignInManager>()
        .AddDefaultTokenProviders();

    services.AddScoped<IUserStore<Employee>, ApplicationUserStore>();
    services.AddScoped<ApplicationUserStore>();
    ...

即使没有:

    services.AddScoped<IUserStore<Employee>, ApplicationUserStore>();

【讨论】:

谢谢!我在 DbContext 依赖注入方面遇到了类似的问题。 (Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService) 并通过在 Startup.cs 文件中输入另一个 services.AddDbContext 项解决了该问题。 我遇到了同样的问题。 ApplicationUserStrore 到底是什么?我无法在提供的链接中找到 ApplicationUserStore 问题中提供的 @T3.0 ApplicationUserStore 是我的自定义用户类型的自定义 IUserStore 谢谢。我向自定义用户类型添加了 isEnabled 属性,但尚未创建自定义用户存储。也许这就是我错误的原因。 Unable to resolve service for type Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore 1[Myapp.Areas.Identity.Data.xyzUser] while attempting to activate Myapp.Areas.Identity.Pages.Account.Manage.CustomUserEditPage.////// at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvider sp, Type type, Type requiredBy, Boolean isDefaultParameterRequired) at lambda_method... 谢谢你,这真的让我摆脱了依赖注入 h*ll!

以上是关于Asp.Net Core 2.1 Identity - UserStore 依赖注入的主要内容,如果未能解决你的问题,请参考以下文章

ViewData 未传递给 ASP.NET Core 2.1 中的布局

asp.net core系列 48 Identity 身份模型自定义

Asp.net Core 2.0 Identity.TwoFactorRememberMe 到期

“Identity.External”的 ASP.NET Core 标识异常

ASP.NET Core MVC 2.x 全面教程_ASP.NET Core MVC 14. ASP.NET Core Identity 入门

ASP.Net Core 如何在 EF Core 和 Identity 中获取用户角色