我正在尝试实现ASP.NET Core中间件,这是我项目中的完整代码:
public class HostMiddleware : IMiddleware
{
public int Count { get; set; }
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
if (context.Request.Query.ContainsKey("hello"))
{
await context.Response.WriteAsync($"Hello World: {++Count}");
}
else
{
await next.Invoke(context);
}
}
}
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IServiceProvider provider)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseMiddleware<HostMiddleware>();
app.Run(async context =>
{
context.Response.StatusCode = 400;
await context.Response.WriteAsync("Bad request.");
});
}
但是,当我运行此服务器时,我收到以下错误:
InvalidOperationException:没有注册“WebApplication4.HostMiddleware”类型的服务。
为什么会出现此错误?如果我在项目中不使用依赖注入,为什么我的中间件需要注册任何服务?
更新
出于某种原因,当我停止使用IMiddleware
,将InvokeAsync
重命名为Invoke
并按以下方式实施我的中间件时,不会发生此错误:
public class WmsHostMiddleware
{
private readonly RequestDelegate _next;
public int Count { get; set; }
public WmsHostMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
if (context.Request.Query.ContainsKey("hello"))
{
await context.Response.WriteAsync($"Hello World: {++Count}");
}
else
{
await _next.Invoke(context);
}
}
}
问题仍然存在 - 为什么会发生这种情况?有什么不同?当我使用IMiddleware
时,为什么需要注册服务。
答案 0 :(得分:4)
今天,当您使用IMiddleware界面时,您还必须将其作为服务添加到依赖注入容器中:
services.AddTransient<HostMiddleware>();
答案 1 :(得分:3)
UseMiddleware
扩展方法的实现使用容器来激活实现IMiddleware
的中间件实例,如果不是这样,它将尝试使用Activator.CreateInstance
创建实例你可以通过UseMiddleware
方法传递的ctor params。
您可以查看source code