Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

No service for type has been registered

I am trying to implement ASP.NET Core middleware, and this is the whole code I have in my project:

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.");
        });
    }

However, when I run this server I get the following error:

InvalidOperationException: No service for type 'WebApplication4.HostMiddleware' has been registered.

developer exception page screenshot

Why do I get this error? Why would my middleware need to register any services if I don't use dependency injection in my project?

Update:

For some reason, this error does not occur when I stop using IMiddleware, rename InvokeAsync to Invoke and implement my middleware in the following way:

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);
        }
    }
}

The question is still open - why does this happen? What is the difference? Why do I need to register services when I use IMiddleware.

like image 747
Yeldar Kurmangaliyev Avatar asked Jan 23 '18 05:01

Yeldar Kurmangaliyev


2 Answers

Today, when you use the IMiddleware interface, you also have to add it to the dependency injection container as a service:

services.AddTransient<HostMiddleware>();
like image 180
davidfowl Avatar answered Nov 11 '22 00:11

davidfowl


Implementation of UseMiddleware extension method uses container to activate instances of middlewares which implement IMiddleware, if that's not the case it will try to create instance using Activator.CreateInstance and additional ctor params which you may pass in UseMiddleware method.

You can take a look at the source code

like image 23
Darjan Bogdan Avatar answered Nov 11 '22 01:11

Darjan Bogdan