-
Notifications
You must be signed in to change notification settings - Fork 10.4k
Implement IProvideEndpointMetadata & IProvideEndpointParameterMetadata #40926
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
if (typeof(IProvideEndpointParameterMetadata).IsAssignableFrom(parameter.ParameterType)) | ||
{ | ||
// Parameter type implements IProvideEndpointParameterMetadata | ||
var metadata = GetMetadataForParameterMethod.MakeGenericMethod(parameter.ParameterType).Invoke(null, new object?[] { parameter, factoryContext.ServiceProvider }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@stephentoub and @davidwrighton, this is the first example of us calling into an interface with a static abstract virtual method from late bound code. Ideally, this would be a helper like:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally, this would be a helper like:
like... :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I brain farted when I wrote this. Originally I had something like:
public class RuntimeHelpers
{
public T StaticCast<T>(Type type);
}
But I think this method would need to be an intrinsic (or something like it) since today a generic constraint is required to make this work normally.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's kinda annoying that we have to define RequestDelegateFacotry.GetMetadataForParameter<T>(...)
in order to call T.GetMetadata(...)
via reflection in the first place. It's defined lower down in the file, but I'll copy it here for reference.
private static IEnumerable<object> GetMetadataForParameter<T>(ParameterInfo parameter, IServiceProvider services)
where T : IProvideEndpointParameterMetadata
{
return T.GetMetadata(parameter, services);
}
In most cases, we could just look for a public GetMetadata
method on T
, but what about explicit interface implementations? AFAIK, you are then forced to get the MethodInfo
from the interface in this case. The problem is that a static abstract
MethodInfo
isn't invocable via reflection since there is no this
parameter and no overload of MethodInfo.Invoke
takes the derived type to call the static method on.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is technically possible to invoke the static abstract completely through reflection. We added support for static abstract methods in the Type.GetInterfaceMap
api. However, that api is rather awkward and slow to use, so if late bound usage is critical, I would welcome proposals for updated reflection apis.
src/Http/Http.Extensions/src/EndpointParameterMetadataContext.cs
Outdated
Show resolved
Hide resolved
src/Http/Http.Extensions/src/EndpointParameterMetadataContext.cs
Outdated
Show resolved
Hide resolved
src/Http/Http.Extensions/src/EndpointParameterMetadataContext.cs
Outdated
Show resolved
Hide resolved
src/Http/Http.Extensions/src/EndpointParameterMetadataContext.cs
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume we're happy with the added InitialEndpointMetadata API?
Implement IProvideEndpointMetadata & IProvideEndpointParameterMetadata
Implements the
IProvideEndpointMetadata
andIProvideEndpointParameterMetadata
interfaces inMicrosoft.AspNetCore.Http
and updatesRequestDelegateFactory
to gather metadata for endpoints when these interfaces are implemented by endpoint request handler delegate parameters, return types, and method attributes.Interfaces were added to the
Microsoft.AspNetCore.Http.Extensions
project. Unit tests added to theRequestDelegateFactoryTests
class.Fixes #40646