某些服务无法构建 [英] Some services are not able to be constructed

查看:56
本文介绍了某些服务无法构建的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个ASP.NET Core 3.1 MVC解决方案,在其中创建了一个用于收集解决方案中常用功能的类.

I have a ASP.NET Core 3.1 MVC solution, where I have created a class for collecting common used functions in the solution.

我已经在此类的startup.cs中注册了该类:

I have registered the class in startup.cs like this:

services.AddSingleton<ITeamFunctions, TeamFunctions>();

该类的接口(ITeamFunctions)如下:

Interface (ITeamFunctions) for the class looks like this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace PI.Interfaces
{
    public interface ITeamFunctions
    {
        Task UpdateTeamStat(int teamId);
        Task<float> CalculatePriceToPay();
    }
}

该类本身是这样的:

using System.Linq;
using System.Security.Claims;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Transactions;

namespace PI.Utility
{
    public class TeamFunctions : ITeamFunctions
    {
        private readonly ApplicationDbContext _db;
        private readonly UserManager<IdentityUser> _userManager;
        private readonly IHttpContextAccessor _httpContextAccessor;

        public TeamFunctions(ApplicationDbContext db, UserManager<IdentityUser> userManager, IHttpContextAccessor httpContextAccessor)
        {
            _db = db;
            _userManager = userManager;
            _httpContextAccessor = httpContextAccessor;
        }

        Task UpdateTeamStat(int teamId)
        {
        //code here
        }

        Task<float> CalculatePriceToPay();
        {
        //code here
        }



运行解决方案时,它会给我这个错误:

When running the solution it gives me this error:

System.AggregateException:'某些服务无法构建(验证服务描述符'ServiceType:PI.Interfaces.ITeamFunctions生存期:Singleton ImplementationType:PI.Utility.TeamFunctions'时出错:无法为类型'解析服务Microsoft.AspNetCore.Identity.UserManager`1 [Microsoft.AspNetCore.Identity.IdentityUser]',同时尝试激活"PI.Utility.TeamFunctions".)'

System.AggregateException: 'Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: PI.Interfaces.ITeamFunctions Lifetime: Singleton ImplementationType: PI.Utility.TeamFunctions': Unable to resolve service for type 'Microsoft.AspNetCore.Identity.UserManager`1[Microsoft.AspNetCore.Identity.IdentityUser]' while attempting to activate 'PI.Utility.TeamFunctions'.)'

在TeamFunction中禁用IdentityUser注入,它抱怨我的ApplicationDbContext.我已经在startup.cs中尝试了范围(用AddScoped更改了AddSingleton),但是没有任何区别.在Core 2.2解决方案中,我可以使用类似的架构.

Disabling IdentityUser injection in the TeamFunction, and it complains about my ApplicationDbContext. I have experimented with scope in startup.cs (changing AddSingleton with AddScoped) but without any difference. I have a similar architecture in a Core 2.2 solution where it works.

想知道我在想什么吗?

完整的startup.cs如下所示:

The complete startup.cs looks like this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.EntityFrameworkCore;
using PI.Data;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using PI.Models;
using Microsoft.AspNetCore.Http;
using PI.Utility;
using PI.Interfaces;
using Microsoft.AspNetCore.Identity.UI.Services;
using PI.Service;
using PI.Installers;

namespace PI
{
    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.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(
                    Configuration.GetConnectionString("DefaultConnection")));

            services.AddDefaultIdentity<ApplicationUser>()
                .AddRoles<IdentityRole>()
                .AddEntityFrameworkStores<ApplicationDbContext>();

            services.Configure<IdentityOptions>(options =>                  
            {
                // Default Password settings.
                options.Password.RequireDigit = false;
                options.Password.RequireLowercase = true;
                options.Password.RequireNonAlphanumeric = false;
                options.Password.RequireUppercase = false;
                options.Password.RequiredLength = 6;
                options.Password.RequiredUniqueChars = 0;
            });

            services.Configure<CookiePolicyOptions>(options =>
            {
                options.CheckConsentNeeded = context => false;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });

            services.AddSession(options =>                                  
            {
                options.Cookie.IsEssential = true;
                options.IdleTimeout = TimeSpan.FromMinutes(60);
                options.Cookie.HttpOnly = true;
            });

            services.AddSingleton<IEmailSender, EmailSender>();
            services.Configure<EmailOptions>(Configuration);
            services.AddSingleton<ITeamFunctions, TeamFunctions>();
            services.AddControllersWithViews();
            services.AddRazorPages().AddRazorRuntimeCompilation();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseDatabaseErrorPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }
            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();
            app.UseSession();                                              

            app.UseAuthentication();
            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapAreaControllerRoute(
                    name: "admin",
                    areaName: "admin",
                    pattern: "Admin/{controller=User}/{action=Index}/{id?}"
                    );

                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{area=Main}/{controller=Home}/{action=Index}/{id?}");
                endpoints.MapRazorPages();
            });

            app.UseCookiePolicy(); 
        }
    }
}

推荐答案

在显示的 ConfigureServices

services.AddDefaultIdentity<ApplicationUser>()
//...

在内部注册 UserManager< ApplicationUser> ,但是要解析的类的构造函数( TeamFunctions )取决于 UserManager< IdentityUser> .

internally registers UserManager<ApplicationUser>, but the constructor of the class to be resolved (TeamFunctions) depends on UserManager<IdentityUser>.

因此,容器不知道如何在启动时基于显示的配置服务来处理该依赖关系,并引发所述异常.

The container therefore does not know how to handle that dependency based on the shown configuration services in startup and throws the stated exception.

更新构造函数以明确期望配置的类型.

Update the constructor to explicitly expect the type that was configured.

//ctor
public TeamFunctions(
    ApplicationDbContext db, 
    UserManager<ApplicationUser> userManager, //<-- note the type used.
    IHttpContextAccessor httpContextAccessor) {

    //...omitted for brevity

}

其次, UserManager 添加了范围服务寿命

Secondly, UserManager is added with scoped service lifetime

//...

services.TryAddScoped<UserManager<TUser>>();

//...

源代码

并且由于作用域生存期在Singleton中不能很好地发挥作用,因此也应将服务添加为作用域.

And since Scoped lifetime does not play well with Singleton, then the service should also be added as scoped.

//...

services.AddScoped<ITeamFunctions, TeamFunctions>();

//...

这篇关于某些服务无法构建的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆