Implement IProvideEndpointMetadata & IProvideEndpointParameterMetadata#40926
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.
@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.
Ideally, this would be a helper like:
like... :)
There was a problem hiding this comment.
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.
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.
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.
BrennanConroy
left a comment
There was a problem hiding this comment.
I assume we're happy with the added InitialEndpointMetadata API?
Implement IProvideEndpointMetadata & IProvideEndpointParameterMetadata
Implements the
IProvideEndpointMetadataandIProvideEndpointParameterMetadatainterfaces inMicrosoft.AspNetCore.Httpand updatesRequestDelegateFactoryto 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.Extensionsproject. Unit tests added to theRequestDelegateFactoryTestsclass.Fixes #40646