Skip to content

Non-allocating Use middleware extension method #31463

@BrennanConroy

Description

@BrennanConroy

Background and Motivation

While profiling an app I noticed the two largest allocations were coming from the Use extension method. A Func<Task> and a lambda capture, equivalent to ~94 bytes per request.

The proposed API will remove both per-request allocations.

Proposed API

namespace Microsoft.AspNetCore.Builder
{
    public static class UseExtensions
    {
        public static IApplicationBuilder Use(this IApplicationBuilder app, Func<HttpContext, Func<Task>, Task> middleware)
+       public static IApplicationBuilder Use(this IApplicationBuilder app, Func<HttpContext, RequestDelegate, Task> middleware)
    }

Usage Examples

Before:

app.Use(async (context, next) =>
{
    await next();
});

New:

app.Use(async (context, next) =>
{
    await next(context);
});

Alternative Designs

No.

Risks

More overloads isn't always great as it can be detrimental to the developer experience. Fortunately the beginning of both the new and old overloads is the same and the only difference will be when invoking the next method.

It would be nice if we could somehow promote using the new overload over the old one to let developers know they can avoid the implicit allocations.

Additional Information

Possible implementation:

public static IApplicationBuilder Use(this IApplicationBuilder app, Func<HttpContext, RequestDelegate, Task> middleware)
{
    return app.Use(next =>
    {
        Func<HttpContext, Task> n = (c) => next(c);
        return context =>
        {
            return middleware(context, n);
        };
    });
}

Metadata

Metadata

Assignees

Labels

api-approvedAPI was approved in API review, it can be implementedarea-networkingIncludes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractionsenhancementThis issue represents an ask for new feature or an enhancement to an existing onefeature-http-abstractions

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions