Aspnetcore.docs: why call next() instead of next(context)

Created on 19 Jul 2018  Â·  4Comments  Â·  Source: dotnet/AspNetCore.Docs

Hi ,
the Middleware use a next() here . The code is pasted here for convenience

 public void Configure(IApplicationBuilder app)
{
    app.Use((context, next) =>
    {
        var cultureQuery = context.Request.Query["culture"];
        if (!string.IsNullOrWhiteSpace(cultureQuery))
        {
            var culture = new CultureInfo(cultureQuery);
            CultureInfo.CurrentCulture = culture;
            CultureInfo.CurrentUICulture = culture;
        }
        // Call the next delegate/middleware in the pipeline
        return next();
    });
    app.Run(async (context) =>
    {
        await context.Response.WriteAsync(
            $"Hello {CultureInfo.CurrentCulture.DisplayName}");
    });
}

I'm wondering why the middleware call a next() instead of a next(context)
Any Help ? Thanks a lot.


Document Details

⚠ Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

P3 Source - Docs.ms

Most helpful comment

@guardrex @Tratcher thanks !

I finally got it by reading the source code here

public static IApplicationBuilder Use(this IApplicationBuilder app, Func<HttpContext, Func<Task>, Task> middleware)
{
    return app.Use(next =>
    {
        return context =>
        {
            Func<Task> simpleNext = () => next(context);   // context is captured here !
            return middleware(context, simpleNext);
        };
    });
}

the next pass to in-line middleware is an instance of Func<Task> which means it has no context parameter . However , the next used in Use() method is a ReqeustDelegate which means it will receive a context parameter and will be wrapped to Func<Task> by : ()=> next(context) .

All 4 comments

@Tratcher It would be good for me to hear this answer, too, as I'm also wrapping a few brain cells around this. It's obvious that next (Func<Task>) doesn't accept an HttpContext. Is it because the context is available to all of the delegates in Configure, so it isn't necessary for each chained delegate to pass the context to the next one?

It's just sugar we added so you had one less redundant parameter. The httpContext is captured inside the next func.

@guardrex @Tratcher thanks !

I finally got it by reading the source code here

public static IApplicationBuilder Use(this IApplicationBuilder app, Func<HttpContext, Func<Task>, Task> middleware)
{
    return app.Use(next =>
    {
        return context =>
        {
            Func<Task> simpleNext = () => next(context);   // context is captured here !
            return middleware(context, simpleNext);
        };
    });
}

the next pass to in-line middleware is an instance of Func<Task> which means it has no context parameter . However , the next used in Use() method is a ReqeustDelegate which means it will receive a context parameter and will be wrapped to Func<Task> by : ()=> next(context) .

Issue documents what's going on. Thanks for pointing this out.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Rick-Anderson picture Rick-Anderson  Â·  3Comments

royshouvik picture royshouvik  Â·  3Comments

wgutierrezr picture wgutierrezr  Â·  3Comments

AnthonyMastrean picture AnthonyMastrean  Â·  3Comments

madelson picture madelson  Â·  3Comments