没有注册类型服务

时间:2018-01-23 05:23:05

标签: c# asp.net-core asp.net-core-middleware

我正在尝试实现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”类型的服务。

developer exception page screenshot

为什么会出现此错误?如果我在项目中不使用依赖注入,为什么我的中间件需要注册任何服务?

更新

出于某种原因,当我停止使用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时,为什么需要注册服务。

2 个答案:

答案 0 :(得分:4)

今天,当您使用IMiddleware界面时,您还必须将其作为服务添加到依赖注入容器中:

services.AddTransient<HostMiddleware>();

答案 1 :(得分:3)

UseMiddleware扩展方法的实现使用容器来激活实现IMiddleware的中间件实例,如果不是这样,它将尝试使用Activator.CreateInstance创建实例你可以通过UseMiddleware方法传递的ctor params。

您可以查看source code