Skip to content

Add access to services for route handler filter factories to RouteHandlerContext #41900

Closed
@DamianEdwards

Description

@DamianEdwards

When adding a route handler filter via a filter factory there are cases where the filter factory (as opposed to the filter itself) needs access to the application services, e.g. to get an ILogger instance. We should add a property to RouteHandlerContext to enable this.

namespace Microsoft.AspNetCore.Http;

public sealed class RouteHandlerContext
{
+    public IServiceProvider ApplicationServices { get; }
}

Note that the property is nullable due to where it's instantiated in RequestDelegateFactory and matches the Services properties on EndpointMetadataContext and EndpointParameterMetadataContext.

Example Usage

public static RouteHandlerBuilder WithParameterValidation(this RouteHandlerBuilder builder, int statusCode = StatusCodes.Status400BadRequest)
{
    builder.Add(eb =>
    {
        var methodInfo = eb.Metadata.OfType<MethodInfo>().SingleOrDefault();
        if (methodInfo is not null && IsValidatable(methodInfo))
        {
            eb.Metadata.Add(new ProducesResponseTypeAttribute(typeof(HttpValidationProblemDetails), statusCode, "application/problem+json"));
        }
    });
    builder.AddFilter((RouteHandlerContext context, RouteHandlerFilterDelegate next) =>
    {
        // *************************************
        // ** We use ApplicationServices here **
        // *************************************
        var loggerFactory = context.ApplicationServices.GetRequiredService<ILoggerFactory>();
        var logger = loggerFactory.Create("MinimalApis.Extensions.Filters.ValidationRouteHandlerFilterFactory");
 
        if (!IsValidatable(context.MethodInfo))
        {
            return next;
        }
 
        return rhic =>
        {
            foreach (var parameter in rhic.Parameters)
            {
                if (parameter is not null && !MiniValidator.TryValidate(parameter, out var errors))
                {
                    return new(Results.ValidationProblem(errors));
                }
            }
 
            return next(rhic);
        };
    });

    return builder;
}

Risks

Should be very low. This is following the pattern used in other context classes including those where the call site originates in RequestDelegateFactory, e.g. EndpointMetadataContext.

Metadata

Metadata

Assignees

Labels

api-approvedAPI was approved in API review, it can be implementedarea-minimalIncludes minimal APIs, endpoint filters, parameter binding, request delegate generator etcfeature-minimal-actionsController-like actions for endpoint routingold-area-web-frameworks-do-not-use*DEPRECATED* This label is deprecated in favor of the area-mvc and area-minimal labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions