【问题标题】:Why do I get this InvalidOperationException: Unable to resolve service for type 'Microsoft.AspNetCore.Http.RequestDelegate'?为什么我会收到此 InvalidOperationException:无法解析类型“Microsoft.AspNetCore.Http.RequestDelegate”的服务?
【发布时间】:2020-04-15 03:47:03
【问题描述】:

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

我已经修复了所有编译时错误,升级了我的 Nuget 包,现在我可以运行该应用了。

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

InvalidOperationException:无法解析服务类型 'Microsoft.AspNetCore.Http.RequestDelegate' 尝试 激活“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()

程序.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() 永远不会运行Build() 方法总是在应用程序到达 Configure() 之前杀死它。

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

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)

【问题讨论】:

  • 你能分享你的 Startup.cs 吗?

标签: c# asp.net-core .net-core asp.net-core-3.1 scrutor


【解决方案1】:

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

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

在我的情况下删除该行

services.AddSingleton<MyMiddleware>();

解决了这个问题。

【讨论】:

    【解决方案2】:

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

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

    我的问题的解决方法是在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;
    });
    

    【讨论】:

      【解决方案3】:

      正如@user1796440 所说,我可以使用services.AddSingleton&lt;MyMiddleware&gt;(); 重现您的问题。

      要修复它,您需要注册如下中间件:

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

      【讨论】:

      • 我想过,但问题是我的Configure() 方法从未被调用过。异常被提前抛出,所以我永远不会到达UseMiddleware()这一点。
      • 那么你能分享你的 Startup.cs 吗?这对解决你的问题会更有帮助。
      猜你喜欢
      • 1970-01-01
      • 2023-01-30
      • 2016-09-19
      • 2021-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-26
      相关资源
      最近更新 更多