带有身份的asp.net核心中的依赖注入错误

Posted

技术标签:

【中文标题】带有身份的asp.net核心中的依赖注入错误【英文标题】:Dependency Injection Error in asp.net core With Identity 【发布时间】:2021-09-02 17:33:25 【问题描述】:

我有使用 Microsoft 标识的应用程序我的模型是 应用用户

public class ApplicationUser : IdentityUser
    
        public string Notes  get; set; 
        public string DisplayName  get; set; 
        public string Firstname  get; set; 
        public string MiddleName  get; set; 
        public string Lastname  get; set; 
        public string Gender  get; set; 
        public string ProfilePic  get; set; 
        public string Birthday  get; set; 
        public bool IsProfileComplete  get; set; 
        public bool Terms  get; set; 
        public bool IsEmployee  get; set; 
        public string UserRole  get; set; 
        public DateTime AccountCreatedOn  get; set; 
        public bool RememberMe  get; set; 
        public bool IsActive  get; set; 
        public ICollection<Address> UserAddresses  get; set; 
    

我的上下文是

public class ApplicationDbContext : IdentityDbContext<ApplicationUser, IdentityRole, string>
    
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
        
        

        protected override void OnModelCreating(ModelBuilder builder)
        
            base.OnModelCreating(builder);
            builder.ApplyConfigurationsFromAssembly(typeof(ApplicationUserConfiguration).Assembly);
            builder.ApplyConfigurationsFromAssembly(typeof(AddressConfigurations).Assembly);
        

        public DbSet<ApplicationUser> ApplicationUsers  get; set; 
        public DbSet<Address> Addresses  get; set; 
    

我的启动文件是

services.AddIdentity<ApplicationUser, IdentityRole>()
            .AddEntityFrameworkStores<ApplicationDbContext>().AddDefaultTokenProviders();
        services.AddScoped<ISeedData, SeedData>();

我正在像这样在 program.cs 中播种数据

public static async Task Main(string[] args)
    
        var host = CreateHostBuilder(args).Build();

        using (var scope = host.Services.CreateScope())
        
            var services = scope.ServiceProvider;
            try
            
                var seedData = services.GetRequiredService<ISeedData>();
                var context = services.GetRequiredService<ApplicationDbContext>();
                await DbInitializer.DataBaseInitialize(seedData, context);
            
            catch (Exception ex)
            
                Log.Error("An error occurred while seeding database Error StackTrace InnerException Source", ex.Message, ex.StackTrace, ex.InnerException, ex.Source);
            
        

        await host.RunAsync();
    

我的存储库接口是 ISeedData 和实现 SeedData

私有只读 UserManager _userManager; 私有只读 RoleManager _roleManager;

    public SeedData(UserManager<ApplicationUser> userManager, RoleManager<IdentityRole> roleManager)
    
        _userManager = userManager;
        _roleManager = roleManager;
    

    public async Task CreateAdminUser()
    

但是当我运行我的应用程序时,我收到了这个错误

    Unhandled exception. System.AggregateException: Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: CMS_DataAccessService.IRepository.ISeedData Lifetime: Scoped ImplementationType: CMS_DataAccessService.Repository.SeedData': Unable to resolve service for type 'Microsoft.AspNetCore.Identity.UserManager`1[CMS_ModelsServices.Models.ApplicationUser]' while attempting to activate 'CMS_DataAccessService.Repository.SeedData'.)
 ---> System.InvalidOperationException: Error while validating the service descriptor 'ServiceType: CMS_DataAccessService.IRepository.ISeedData Lifetime: Scoped ImplementationType: CMS_DataAccessService.Repository.SeedData': Unable to resolve service for type 'Microsoft.AspNetCore.Identity.UserManager`1[CMS_ModelsServices.Models.ApplicationUser]' while attempting to activate 'CMS_DataAccessService.Repository.SeedData'.
 ---> System.InvalidOperationException: Unable to resolve service for type 'Microsoft.AspNetCore.Identity.UserManager`1[CMS_ModelsServices.Models.ApplicationUser]' while attempting to activate 'CMS_DataAccessService.Repository.SeedData'.
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateArgumentCallSites(Type serviceType, Type implementationType, CallSiteChain callSiteChain, ParameterInfo[] parameters, Boolean throwIfCallSiteNotFound)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateConstructorCallSite(ResultCache lifetime, Type serviceType, Type implementationType, CallSiteChain callSiteChain)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateExact(ServiceDescriptor descriptor, Type serviceType, CallSiteChain callSiteChain, Int32 slot)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.GetCallSite(ServiceDescriptor serviceDescriptor, CallSiteChain callSiteChain)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.ValidateService(ServiceDescriptor descriptor)
   --- End of inner exception stack trace ---
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.ValidateService(ServiceDescriptor descriptor)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider..ctor(IEnumerable`1 serviceDescriptors, IServiceProviderEngine engine, ServiceProviderOptions options)
   --- End of inner exception stack trace ---
   at Microsoft.Extensions.DependencyInjection.ServiceProvider..ctor(IEnumerable`1 serviceDescriptors, IServiceProviderEngine engine, ServiceProviderOptions options)
   at Microsoft.Extensions.DependencyInjection.ServiceCollectionContainerBuilderExtensions.BuildServiceProvider(IServiceCollection services, ServiceProviderOptions options)
   at Microsoft.Extensions.DependencyInjection.DefaultServiceProviderFactory.CreateServiceProvider(IServiceCollection containerBuilder)
   at Microsoft.Extensions.Hosting.Internal.ServiceFactoryAdapter`1.CreateServiceProvider(Object containerBuilder)
   at Microsoft.Extensions.Hosting.HostBuilder.CreateServiceProvider()
   at Microsoft.Extensions.Hosting.HostBuilder.Build()
   at CMS.Program.Main(String[] args) in E:\Projects\CMS\CMS\Program.cs:line 24
   at CMS.Program.<Main>(String[] args)

【问题讨论】:

我想我错了。我删除了之前的评论。我在想,即使它是相同的例外,引用的副本也可能在这里不适用。您似乎已在启动时正确注册了该类型,但尝试在 services.ServiceProvider 的服务中使用(解析类型)确实是这个问题的范围。据推测,您在控制器中解析这些类型不会有问题。 我无法重现此错误。在Main 函数范围内,它使用使用这些类型的示例构造函数解析为SeedData(和context)的实例。您能否验证 CMS_ModelsServices.Models.ApplicationUser 是在您的启动文件范围中引用和使用的类型。你能从你的启动文件中提供整个ConfigureServices 范围吗?你能指定你正在使用什么目标框架(我的目标是net5),并包括依赖包及其版本。 你可以在github.com/adelanwer12/CMS找到完整的代码 【参考方案1】:

您的代码库中有 2 个 ApplicationUser 类型。

您为依赖注入注册的是CMS_DataServices.Models.ApplicationUser

SeedData 构造函数中使用的是CMS_ModelsServices.Models.ApplicationUser

要解决,只需确保在两个方面都使用相同的类型。

services.AddIdentity<CMS_ModelsServices.Models.ApplicationUser, IdentityRole>()
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddDefaultTokenProviders();
services.AddScoped<ISeedData, SeedData>();

【讨论】:

以上是关于带有身份的asp.net核心中的依赖注入错误的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET Core RC2 中的依赖注入失败

如何使用构造函数依赖注入对 asp.net 核心应用程序进行单元测试

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

具有多个构造函数的 ASP.NET Core 依赖注入

未调用 ASP.NET Core 3 中依赖注入服务的具体实现

[ASP.NET Core 3框架揭秘] 依赖注入:一个Mini版的依赖注入框架