Никаких услуг для типа не зарегистрировано

Я пытаюсь реализовать промежуточное ПО 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.


person Yeldar Kurmangaliyev    schedule 23.01.2018    source источник


Ответы (2)


Реализация метода расширения UseMiddleware использует контейнер для активации экземпляров промежуточного программного обеспечения, реализующего IMiddleware, если это не так, он попытается создать экземпляр, используя Activator.CreateInstance и дополнительные параметры ctor, которые вы можете передать в метод UseMiddleware.

Вы можете взглянуть на исходный код

person Darjan Bogdan    schedule 23.01.2018

Сегодня, когда вы используете интерфейс IMiddleware, вам также необходимо добавить его в контейнер внедрения зависимостей в качестве службы:

services.AddTransient<HostMiddleware>();
person davidfowl    schedule 25.01.2018
comment
PS: Я отправил PR, чтобы сделать это так, чтобы это не требовалось github.com/aspnet/HttpAbstractions / pull / 988 - person davidfowl; 25.01.2018
comment
Хммм, ваш PR объединен около года назад, и это все еще требуется в ASP.NET Core 2.2. Было ли это отменено? - person Saeb Amini; 18.01.2019
comment
Часть его была возвращена. Вам также необходимо добавить промежуточное ПО как услугу. Утилизация была проблемой - person davidfowl; 19.01.2019
comment
@davidfowl, что предпочтительнее services.AddSingleton или services.AddTransient? - person Arjun Vachhani; 20.04.2019
comment
Для IMiddleware он должен быть временным, поскольку предполагается, что он создается и уничтожается по запросу. - person davidfowl; 20.04.2019