为什么会出现此 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()
从来没有 运行s。 Build()
方法总是在到达 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>();
//...
}
这个问题的解决方案包含两个主要元素:
- .NET Core 3.0 引入了关于服务提供商验证.
的更改
- 我的代码是注册太多类,导致验证失败。
我的问题的解决方案是在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;
});
我刚刚将我的 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()
从来没有 运行s。 Build()
方法总是在到达 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>();
//...
}
这个问题的解决方案包含两个主要元素:
- .NET Core 3.0 引入了关于服务提供商验证. 的更改
- 我的代码是注册太多类,导致验证失败。
我的问题的解决方案是在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;
});