-
Notifications
You must be signed in to change notification settings - Fork 10.4k
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.