验证服务描述符时出错 'ServiceType ...'

Error while validating the service descriptor 'ServiceType ...'

我正在使用 Identity.

进行 ASP.net 核心 项目

我尝试做的事情:

我尝试让网络应用程序创建新的默认 userroles

一切都很好,直到我在 Startup ConfigureServices class

中添加并调用了一个方法

之后我得到了这个error/exception

System.AggregateException: 'Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: Microsoft.AspNetCore.Mvc.Razor.Compilation.IViewCompilerProvider Lifetime: Singleton ImplementationType: Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation.RuntimeViewCompilerProvider': Unable to resolve service for type 'Microsoft.AspNetCore.Mvc.ApplicationParts.ApplicationPartManager' while attempting to activate 'Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation.RuntimeViewCompilerProvider'.) (Error while validating the service descriptor 'ServiceType: Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation.RazorReferenceManager Lifetime: Singleton ImplementationType: Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation.RazorReferenceManager': Unable to resolve service for type 'Microsoft.AspNetCore.Mvc.ApplicationParts.ApplicationPartManager' while attempting to activate 'Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation.RazorReferenceManager'.) (Error while validating the service descriptor 'ServiceType: Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation.CSharpCompiler Lifetime: Singleton ImplementationType: Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation.CSharpCompiler': Unable to resolve service for type 'Microsoft.AspNetCore.Mvc.ApplicationParts.ApplicationPartManager' while attempting to activate 'Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation.RazorReferenceManager'.)'

ConfigureServices 方法:

public async Task ConfigureServices(IServiceCollection services, IServiceProvider serviceProvider)
{
    services.AddDbContext<AppDbContext>(options =>
        options.UseSqlServer(
            Configuration.GetConnectionString("DefaultConnection")));
    services.AddDatabaseDeveloperPageExceptionFilter();

    services.AddIdentity<AppUser, IdentityRole>(options => options.SignIn.RequireConfirmedAccount = true)
            .AddClaimsPrincipalFactory<UserClaimsPrincipalFactory<AppUser, IdentityRole>>()
            .AddEntityFrameworkStores<AppDbContext>().AddDefaultTokenProviders().AddDefaultUI();

    services.AddControllersWithViews();
    services.AddRazorPages();

    //This is the method I try to call
     await CreateDefaultRoles(serviceProvider);
}

我尝试调用的方法:

  public async Task CreateDefaultRoles(IServiceProvider serviceProvider)
        {
            var userManager      = serviceProvider.GetRequiredService<UserManager<AppUser>>();
            var roleManager      = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>();
            bool isAdminRoleExist = await roleManager.RoleExistsAsync("Admin");

            if (!isAdminRoleExist)
            {
                var roleResult = await roleManager.CreateAsync(new IdentityRole(Roles.Admin.ToString()));
            }

            var defaultAdminUser = await userManager.FindByNameAsync("Admin");

            if (defaultAdminUser == null)
            {
                AppUser defaultAdmin = new AppUser()
                                       {
                                           UserName = "Admin",
                                           Email    = "my@email.com"
                                       };
                var defaultAdminTask = await userManager.CreateAsync(defaultAdmin, "MYP@ssword2021");

                if (defaultAdminTask.Succeeded)
                {
                    var adminToRoleTask = await userManager.AddToRoleAsync(defaultAdmin, Roles.Admin.ToString());
                }
            }
        }

请帮忙解决这个问题??

我建议将播种移动到 Configure(),因为在 ConfigureServices()ServiceProvider 尚未构建,因为您只是在配置它。

您可以调用 services.BuildServiceProvider(),但这是有问题的,并且没有必要这样做,因为您可以在 Configure().

中很好地实现播种

主要是在一个新的scope中做整个seeding,然后dispose。

这是一个可靠的方法,例如:


public async Task Configure(IApplicationBuilder app)
{
    ...
    await CreateDefaultRoles(app);
    ...
}

public async Task CreateDefaultRoles(IApplicationBuilder appBuilder)
{
    using (var scope = appBuilder.ApplicationServices.CreateScope())
    {
        var serviceProvider = scope.ServiceProvider;

        var userManager = serviceProvider.GetRequiredService<UserManager<AppUser>>();
        var roleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>();
        // Do your seeding stuff
    }
}

我只能假设 Configure() 作为 async 方法工作;从来没有尝试过那样使用它。我只是用同步方法为数据库播种。

如果此解决方案不适合您,请告诉我。