为什么会出现此 InvalidOperationException:无法解析类型 'Microsoft.AspNetCore.Http.RequestDelegate' 的服务?

Why do I get this InvalidOperationException: Unable to resolve service for type 'Microsoft.AspNetCore.Http.RequestDelegate'?

我刚刚将我的 ASP.NET Core WebApi 项目从 .NET Core 2.2 升级到 3.1.

我已经修复了所有 compile-time 错误,升级了我的 Nuget 包,现在我可以 运行 应用程序了。

但是,当我在 IHostBuilder 上调用 Build() 时,出现以下异常:

InvalidOperationException: Unable to resolve service for type 'Microsoft.AspNetCore.Http.RequestDelegate' while attempting to activate 'MyProject.Api.Middleware.ExceptionHandlerMiddleware'.

它所指的中间件非常标准。

ExceptionHandlerMiddleware.cs

public class ExceptionHandlerMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ILogger<ExceptionHandlerMiddleware> _logger;

    public ExceptionHandlerMiddleware(RequestDelegate next, ILogger<ExceptionHandlerMiddleware> logger)
    {
        _logger = logger;
        _next = next;
    }

    public async Task InvokeAsync(HttpContext httpContext)
    {
        // redacted
    }
}

我的应用程序初始化的其余部分是相当标准的,从 2.2 到 3.1(2.2 正在运行)我没有做太多改变。

我确实从 services.AddMvc() 更改为 services.AddControllers()

Program.cs

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    private static IHostBuilder CreateHostBuilder(string[] args)
    {
        return Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(builder =>
            {
                builder.UseSerilog().UseStartup<Startup>();
            })
            .ConfigureLogging((context, logging) =>
            {
                logging
                .AddConfiguration(context.Configuration.GetSection("Logging"))
                .AddConsole()
                .AddDebug();
            });
    }
}

另外值得一提的是 Startup.cs 中的 ConfigureServices() 方法被调用并且 运行 没问题,但是 Configure() 从来没有 运行sBuild() 方法总是在到达 Configure().

之前终止应用程序

我的 Startup 的 Configure 方法签名如下所示:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)

我运行今天遇到同样的问题,解决方法如下:

在 .net core 2.2 中,我将中间件添加到应用程序构建器,并将中间件添加到服务集合。显然不再需要将中间件添加到服务集合中,这会导致您发布异常。

在我的例子中删除行

services.AddSingleton<MyMiddleware>();

已解决问题。

如@user1796440 所说,我可以使用 services.AddSingleton<MyMiddleware>();.

重现您的问题

要修复它,您需要像下面这样注册中间件:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    //...
    app.UseMiddleware<ExceptionHandlerMiddleware>();
    //...
}

这个问题的解决方案包含两个主要元素:

  1. .NET Core 3.0 引入了关于服务提供商验证.
  2. 的更改
  3. 我的代码是注册太多类,导致验证失败。

我的问题的解决方案是在Program.cs中引入以下代码:

private static IHostBuilder CreateHostBuilder(string[] args)
{
    return Host.CreateDefaultBuilder(args)
        .UseDefaultServiceProvider(opt =>
        {
            // this overrides the default service provider options
            // so that it doesn't validate the service collection (which raises exceptions)
        })
        [ ... ]
}

感谢其他回答让我注意到我的 Startup.cs

完整解释

我使用 Scrutor 扫描程序集并自动注册 类。 Scrutor 正在寻找并注册我的中间件 类 例如ExceptionHandlerMiddleware.

它在 .NET Core 2.2 和 3.1 中都是这样做的。那么为什么它只在 Core 3.1 中中断?

因为 .NET Core 3.0 引入了 Generic Host 作为构建主机的新默认方式。

该代码现在包含在开发环境下默认启用ValidateOnBuild的部分。这导致我的 ServiceProvider 在构建时进行验证。它无法解析 RequestDelegate 因为我没有注册它。

.UseDefaultServiceProvider((context, options) =>
{
    var isDevelopment = context.HostingEnvironment.IsDevelopment();
    options.ValidateScopes = isDevelopment;
    options.ValidateOnBuild = isDevelopment;
});