No service for type has been registered

16,443

Solution 1

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

Solution 2

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

services.AddTransient<HostMiddleware>();
Share:
16,443
Yeldar Kurmangaliyev
Author by

Yeldar Kurmangaliyev

Full-stack software engineer with vast experience in system design and development, mostly in finance and banking sector. Extended professional and personal info at kurmangaliyev.kz

Updated on July 12, 2022

Comments

  • Yeldar Kurmangaliyev
    Yeldar Kurmangaliyev almost 2 years

    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.

  • davidfowl
    davidfowl over 6 years
    PS: I submitted a PR to make it so this isn't required github.com/aspnet/HttpAbstractions/pull/988
  • Saeb Amini
    Saeb Amini over 5 years
    Hmmm, your PR is merged about a year ago and this is still required in ASP.NET Core 2.2. Was it reverted?
  • davidfowl
    davidfowl over 5 years
    Part of it was reverted. You need to add the middleware as a service as well. Disposal was a problem
  • Arjun Vachhani
    Arjun Vachhani about 5 years
    @davidfowl what is prefered services.AddSingleton or services.AddTransient ?
  • davidfowl
    davidfowl about 5 years
    For IMiddleware, it should be transient as the intent is that it's created and destroyed per request
  • maartenba
    maartenba over 2 years
    AddSingleton also works in (tried in .net core 6 )