app.Use vs Middleware–and scoped services

When you want to use a fast middleware , you can use ( pun intended)

app.Use(

However, if you want to use some of scoped services , e.g.

app.Use(async (context, next) =>
{
     var st= app.Services.GetRequiredService<IServerTiming>();

//code

}

then it gives an error

Cannot resolve scoped service  from root provider

For this you should create  a scope:

app.Use(async (context, next) =>
{
     //var st= app.Services.GetRequiredService<IServerTiming>();
     using var sc = app.Services.CreateScope();
     var st = sc.ServiceProvider.GetRequiredService<IServerTiming>();
     st.AddMetric((decimal)0.002, “yrequest”);
     await next(context);
});

However, that means it will NOT be the same scope as the original app . How we can have the same scope ?  By using the middleware

public class ServerTiming : IMiddleware
{
     private readonly IServerTiming serverTiming;

    public ServerTiming(IServerTiming serverTiming)
     {
         this.serverTiming = serverTiming;
     }
     public async Task InvokeAsync(HttpContext context, RequestDelegate next)
     {
         this.serverTiming.AddMetric((decimal)0.001, “startRequest”);
         await next(context);              
     }
}

and registering ( code for .net 6 , you can easy make it for .net <6 )

builder.Services.AddScoped<ServerTiming>();
var app = builder.Build();
app.UseMiddleware<ServerTiming>();

This way we are sure that we have the same scoped data.