Skip to content

Update Endpoint metadata providers to include EndpointBuilder param #43125

@halter73

Description

@halter73

Background and Motivation

With #43000, we've approved adding RequestDelegateFactoryOptions.EndpointBuilder and EndpointFilterFactoryContext.EndpointBuilder so filters can get full access to more metadata like the RoutePattern (with a downcast) and DisplayName.

I think IEndpointMetadataProvider and IEndpointParameterMetadataProvider deserve the same treatment.

Also see #42827 (comment) for more context.

Proposed API

namespace Microsoft.AspNetCore.Http.Metadata;


public interface IEndpointMetadataProvider
{
-     static abstract void PopulateMetadata(EndpointMetadataContext context);
+     static abstract void PopulateMetadata(MethodInfo method, EndpointBuilder builder);
}

public interface IEndpointParameterMetadataProvider
{
-     static abstract void PopulateMetadata(EndpointParameterMetadataContext parameterContext);
+     static abstract void PopulateMetadata(ParameterInfo parameter, EndpointBuilder builder);
}

- public sealed class EndpointMetadataContext
- {
-     public EndpointMetadataContext(MethodInfo method, IList<object> endpointMetadata, IServiceProvider applicationServices);
-     public MethodInfo Method { get; }
-     public IList<object> EndpointMetadata { get; }
-     public IServiceProvider ApplicationServices { get; }
- }

- public sealed class EndpointParameterMetadataContext
- {
-     public EndpointParameterMetadataContext(ParameterInfo parameter, IList<object> endpointMetadata, IServiceProvider applicationServices);
-     public ParameterInfo Parameter { get; }
-     public IList<object> EndpointMetadata { get; }
-     public IServiceProvider ApplicationServices { get; }
- }

Usage Examples

static void IEndpointMetadataProvider.PopulateMetadata(MethodInfo method, EndpointBuilder builder)
{
    builder.Metadata.Add(new ProducesResponseTypeMetadata(typeof(TValue), StatusCodes.Status200OK, "application/json"));
}

Alternative Designs

We could change context. to reference a builder in case we want to add more parameters in the future that are not on the EndpointBuilder in some way. I find this is clunky though, and I'm not sure how likely additional future parameters really are.

namespace Microsoft.AspNetCore.Http.Metadata;

public sealed class EndpointMetadataContext
{
-     public EndpointMetadataContext(MethodInfo method, IList<object> endpointMetadata, IServiceProvider applicationServices);
+     public EndpointMetadataContext(MethodInfo method, EndpointBuilder builder);

      public MethodInfo Method { get; }
-     public IList<object> EndpointMetadata { get; }
-     public IServiceProvider ApplicationServices { get; }
+     public EndpointBuilder EndpointBuilder { get; }
}

public sealed class EndpointParameterMetadataContext
{
-     public EndpointParameterMetadataContext(ParameterInfo parameter, IList<object> endpointMetadata, IServiceProvider applicationServices);
-     public EndpointParameterMetadataContext(ParameterInfo prameter, EndpointBuilder builder);

       public ParameterInfo Parameter { get; }
-     public IList<object> EndpointMetadata { get; }
-     public IServiceProvider ApplicationServices { get; }
+     public EndpointBuilder EndpointBuilder { get; }
}

Risks

With the primary proposal, we lose out on having a context, so it's harder to add parameters in the future if we find it will be necesarry.

Third-party IEndpointMetadataProvider implementations need to rewrite their PopulateMetadata methods with either change, but it should be pretty mechanical.

@DamianEdwards

Metadata

Metadata

Assignees

Labels

api-approvedAPI was approved in API review, it can be implementedold-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