-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Description
Background and Motivation
In reaction to #42592, I think we should expose the entire EndopintBuilder via RequestDelegateFactoryOptions. This would allow downcasting to RouteEndpointBuilder and seeing the RoutePattern too from filters.
Proposed API
namespace Microsoft.AspNetCore.Http;
public sealed class RequestDelegateFactoryOptions
{
- public IReadOnlyList<Func<EndpointFilterFactoryContext, EndpointFilterDelegate, EndpointFilterDelegate>>? EndpointFilterFactories { get; init; }
- public IList<object>? EndpointMetadata { get; init; }
+ public EndpointBuilder? EndpointBuilder { get; init; }
}namespace Microsoft.AspNetCore.Http;
public sealed class EndpointFilterFactoryContext
{
- public EndpointFilterFactoryContext(MethodInfo methodInfo, IList<object> endpointMetadata, IServiceProvider applicationServices);
+ public EndpointFilterFactoryContext(MethodInfo methodInfo, EndpointBuilder endopintBuilder);
- public IList<object> EndpointMetadata { get; }
- public IServiceProvider ApplicationServices { get; }
+ public EndpointBuilder EndpointBuilder { get; }
}Usage Examples
Before:
RequestDelegateFactoryOptions factoryOptions = new()
{
ServiceProvider = _applicationServices,
RouteParameterNames = routeParamNames,
ThrowOnBadRequest = _throwOnBadRequest,
DisableInferBodyFromParameters = ShouldDisableInferredBodyParameters(entry.HttpMethods),
EndpointMetadata = builder.Metadata,
// builder.EndopintFilterFactories is not settable so is always a List.
EndpointFilterFactories = (IReadOnlyList<Func<EndpointFilterFactoryContext, EndpointFilterDelegate, EndpointFilterDelegate>>)builder.EndpointFilterFactories,
};After:
RequestDelegateFactoryOptions factoryOptions = new()
{
ServiceProvider = _applicationServices,
RouteParameterNames = routeParamNames,
ThrowOnBadRequest = _throwOnBadRequest,
DisableInferBodyFromParameters = ShouldDisableInferredBodyParameters(entry.HttpMethods),
EndpointBuilder = builder,
};Alternative Designs
We could keep the filter factories directly on RequestDelegateFactoryOptions but rename EndpointFilterFactories to FilterFactories to match the name in EndpointBuilder and make it an IList instead of IReadOnlyList which aligns with RequestDelegateFactoryOptions.Metadata.
namespace Microsoft.AspNetCore.Http;
public sealed class RequestDelegateFactoryOptions
{
- public IReadOnlyList<Func<EndpointFilterFactoryContext, EndpointFilterDelegate, EndpointFilterDelegate>>? EndpointFilterFactories { get; init; }
+ public IList<Func<EndpointFilterFactoryContext, EndpointFilterDelegate, EndpointFilterDelegate>>? FilterFactories { get; init; }
}We could also keep it as an IReadOnlyList. Arguably this communicates better that the RequestDelegateFactory won't mutate it. RDF does mutate EndpointMetadata which is an IList so that might add to the confusion.
Risks
Low. This affects API that has only been released in previews and few people depend on.