【问题标题】:Unable to resolve service for type Microsoft.AspNetCore.Identity.RoleManager无法解析 Microsoft.AspNetCore.Identity.RoleManager 类型的服务
【发布时间】:2020-12-18 12:45:07
【问题描述】:

我正在使用微服务架构开发项目,我使用 ASP.NET Core Identity 作为单独的微服务来创建用户和角色。我使用自定义字段扩展用户和角色,并在我的 API 项目的 startup.cs 中配置身份。但是,当我运行我的应用程序时,出现以下错误,

无法构造某些服务(验证服务描述符时出错“ServiceType: Microservice.IdentityMS.Application.Interfaces.IIdentityMSService Lifetime: Transient ImplementationType: Microservice.IdentityMS.Application.Services.IdentityMSService”:无法解析服务尝试激活“Alexa.IdentityMS.Data.Repository.IdentityMSRepository”时输入“Microsoft.AspNetCore.Identity.RoleManager`1[Microservice.IdentityMS.Domain.Models.MembershipRole]”。)

这是我的身份微服务启动

Startup.cs:

using Microservice.IdentityMS.Data.Context;
using Microservice.IdentityMS.Domain.Models;
using Microservice.Infra.IoC;
using MediatR;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.OpenApi.Models;
using Npgsql;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Microservice.Identity.Api
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();           
            var userConnectionString = Configuration["DbContextSettings:UserConnectionString"];
            var dbPassword = Configuration["DbContextSettings:DbPassword"];           
            var userBuilder = new NpgsqlConnectionStringBuilder(userConnectionString)
            {
                Password = dbPassword
            };

            services.AddDbContext<MembershipDBContext>(opts => opts.UseNpgsql(builder.ConnectionString));
            services.AddDbContext<UserDBContext>(opts => opts.UseNpgsql(userBuilder.ConnectionString));

            services.AddIdentity<MembershipUser, MembershipRole>(options =>
            {
                options.Password.RequiredLength = 8;
                options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+ ";
                options.SignIn.RequireConfirmedEmail = false;
            }).AddRoles<MembershipRole>().AddEntityFrameworkStores<MembershipDBContext>()
            .AddDefaultTokenProviders();            

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_3_0);

            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo { Title = "Identity Microservice", Version = "v1" });
            });
            services.AddMediatR(typeof(Startup));
            RegisterServices(services);
        }
        private void RegisterServices(IServiceCollection services)
        {
            DependencyContainer.RegisterServices(services);
        }
        
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseHttpsRedirection();

            app.UseSwagger();
            app.UseSwaggerUI(c =>
            {
                c.SwaggerEndpoint("/swagger/v1/swagger.json", "Identity Microservice V1");
            });
            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
}

DependencyContainer.cs:

using MediatR;
using Microservices.Domain.Core.Bus;
using Microservices.Infra.Bus;
using Microsoft.Extensions.DependencyInjection;
using Microservices.ProductMS.Domain.Interfaces;
using Microservices.ProductMS.Data.Repository;
using Microservices.ProductMS.Data.Context;
using Microservices.ProductMS.Application.Interfaces;
using Microservices.ProductMS.Application.Services;
using Microservices.PartyMS.Application.Interfaces;
using Microservices.PartyMS.Application.Services;
using Microservices.PartyMS.Domain.Interfaces;
using Microservices.PartyMS.Data.Repository;
using Microservices.PartyMS.Data.Context;
using Microservices.MasterMS.Application.Interfaces;
using Microservices.MasterMS.Application.Services;
using Microservices.MasterMS.Domain.Interfaces;
using Microservices.MasterMS.Data.Repository;
using Microservices.MasterMS.Data.Context;
using Microservices.MasterMS.Domain.Commands;
using Microservices.MasterMS.Domain.CommandHandler;
using Microservices.ProductMS.Domain.Commands;
using Microservices.ProductMS.Domain.CommandHandler;
using Microservices.PartyMS.Domain.CommandHandler;
using Microservices.AccountMS.Application.Interfaces;
using Microservices.AccountMS.Application.Services;
using Microservices.AccountMS.Domain.Interfaces;
using Microservices.AccountMS.Data.Repository;
using Microservices.AccountMS.Data.Context;
using Microservices.SalesPurchaseMS.Domain.Interfaces;
using Microservices.SalesPurchaseMS.Data.Repository;
using Microservices.SalesPurchaseMS.Data.Context;
using Microservices.SalesPurchaseMS.Application.Interfaces;
using Microservices.SalesPurchaseMS.Application.Services;
using Microservices.IdentityMS.Application.Interfaces;
using Microservices.IdentityMS.Application.Services;
using Microservices.IdentityMS.Domain.Interfaces;
using Microservices.IdentityMS.Data.Repository;
using Microservices.IdentityMS.Data.Context;
using Microsoft.AspNetCore.Identity;
using Microservices.IdentityMS.Domain.Models;

namespace Microservices.Infra.IoC
{
    public class DependencyContainer
    {
        public static void RegisterServices(IServiceCollection services)
        {
            //Domain Bus
            services.AddSingleton<IEventBus, RabbitMQBus>(sp =>
            {
                var scopeFactory = sp.GetRequiredService<IServiceScopeFactory>();
                return new RabbitMQBus(sp.GetService<IMediator>(), scopeFactory);
            });

            //Subscriptions
            services.AddTransient<ProductMS.Domain.EventHandler.CompanyEventHandler>();
            services.AddTransient<PartyMS.Domain.EventHandler.CompanyEventHandler>();
            

            //Domain Events
            services.AddTransient<IEventHandler<ProductMS.Domain.Events.CompanyEvent>, ProductMS.Domain.EventHandler.CompanyEventHandler>();
            services.AddTransient<IEventHandler<PartyMS.Domain.Events.CompanyEvent>, PartyMS.Domain.EventHandler.CompanyEventHandler>();
            //services.AddTransient<IEventHandler<SalesMS.Domain.Events.CompanyEvent>, SalesMS.Domain.EventHandler.CompanyEventHandler>();
            //services.AddTransient<IEventHandler<SalesMS.Domain.Events.PartyEvent>, SalesMS.Domain.EventHandler.PartyEventHandler>();

            //Domain Commands
            services.AddTransient<IRequestHandler<CompanySyncCommand, bool>, CompanySyncCommandHandler>();
            services.AddTransient<IRequestHandler<ProductSyncCommand, bool>, ProductSyncCommandHandler>();
            services.AddTransient<IRequestHandler<ProductCategorySyncCommand, bool>, ProductCategorySyncCommandHandler>();
            services.AddTransient<IRequestHandler<PartySyncCommand, bool>, PartySyncCommandHandler>();

            //Application Services            
            services.AddTransient<IMasterService, MasterService>();
            services.AddTransient<IProductService, ProductService>();
            services.AddTransient<IPartyMSService, PartyMSService>();
            //services.AddTransient<IPurchaseService, PurchaseService>();
            services.AddTransient<IPurchaseService, PurchaseService>();
            services.AddTransient<ISaleService, SaleService>();//SaleMS
            services.AddTransient<IAccountMSService, AccountMSService>();
            services.AddTransient<IIdentityMSService, IdentityMSService>();
            services.AddTransient<IAdministrationService, AdministrationService>();

            //Data            
            services.AddTransient<IMasterRepository, MasterRepository>();
            services.AddTransient<MasterDbContext>();

            services.AddTransient<IProductRepository, ProductRepository>();
            services.AddTransient<ProductsDBContext>();
            
            services.AddTransient<IPartyMSRepository, PartyMSRepository>();
            services.AddTransient<PartyMSDBContext>();

            services.AddTransient<IPurchaseRepository, PurchaseRepository>();
            services.AddTransient<ISaleRepository, SaleRepository>();
            services.AddTransient<SPDBContext>();


            services.AddTransient<IAccountMSRepository, AccountMSRepository>();
            services.AddTransient<AccountDbContext>();

            services.AddTransient<IIdentityMSRepository, IdentityMSRepository>();
            services.AddTransient<IAdministrationRepository, AdministrationRepository>();//IdentityMS
            services.AddTransient<UserDBContext>();
        }
    }
}

IdentityMSRepository.cs:

public class IdentityMSRepository : IIdentityMSRepository
{
    private readonly UserDBContext _userContext;
    private readonly RoleManager<MembershipRole> _roleManager;
    private readonly UserManager<MembershipUser> _userManager;

    public IdentityMSRepository(UserDBContext userContext, RoleManager<MembershipRole> roleManager, UserManager<MembershipUser> userManager)
    {
        _userContext = userContext;
        _roleManager = roleManager;
        _userManager = userManager;
    }
}

我错过了什么?

【问题讨论】:

  • 它在我的项目中运行良好。将DependencyContainer中的服务直接移动到Startup而不是使用DependencyContainer.RegisterServices(services);怎么样?如果运行良好,请分享您的DependencyContainer
  • DependencyContainer 还包含其他微服务存储库和服务,这就是我将其保留为单独的类项目的原因。
  • @Rena 你有什么想法吗?我仍然坚持这个。
  • 其实没有。我把它们放在其他类项目中但仍然运行良好。试试其他生命周期怎么样,services.AddSingleton&lt;IIdentityMSRepository, IdentityMSRepository&gt;();AddTransient

标签: asp.net-core microservices asp.net-core-webapi asp.net-core-3.1 asp.net-core-identity


【解决方案1】:

最后我按照评论的建议进行了更改,我将它从 DI 容器移动到启动文件并且它正在工作。 @Rena 非常感谢。

【讨论】:

    猜你喜欢
    • 2021-06-20
    • 2019-10-29
    • 2021-06-11
    • 1970-01-01
    • 1970-01-01
    • 2020-08-16
    • 2022-01-10
    • 2020-03-13
    • 2019-02-10
    相关资源
    最近更新 更多