Skip to content

Commit d0bef45

Browse files
Copilotcaptainsafia
andcommitted
Fix FromKeyedServicesAttribute and FromServicesAttribute to support derived types
- Replace OfType<FromKeyedServicesAttribute>() with IsAssignableFrom checks in BindingInfo.cs - Replace OfType<FromKeyedServicesAttribute>() with IsAssignableFrom checks in RequestDelegateFactory.cs - Update SignalR HubMethodDescriptor pattern matching to handle derived FromKeyedServicesAttribute types - Add test for derived FromKeyedServicesAttribute detection Co-authored-by: captainsafia <1857993+captainsafia@users.noreply.github.com>
1 parent f1baba6 commit d0bef45

File tree

4 files changed

+31
-4
lines changed

4 files changed

+31
-4
lines changed

src/Http/Http.Extensions/src/RequestDelegateFactory.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -803,15 +803,15 @@ private static Expression CreateArgument(ParameterInfo parameter, RequestDelegat
803803
}
804804
else if (parameter.CustomAttributes.Any(a => typeof(IFromServiceMetadata).IsAssignableFrom(a.AttributeType)))
805805
{
806-
if (parameterCustomAttributes.OfType<FromKeyedServicesAttribute>().FirstOrDefault() is not null)
806+
if (parameterCustomAttributes.FirstOrDefault(a => typeof(FromKeyedServicesAttribute).IsAssignableFrom(a.GetType())) is not null)
807807
{
808808
throw new NotSupportedException(
809809
$"The {nameof(FromKeyedServicesAttribute)} is not supported on parameters that are also annotated with {nameof(IFromServiceMetadata)}.");
810810
}
811811
factoryContext.TrackedParameters.Add(parameter.Name, RequestDelegateFactoryConstants.ServiceAttribute);
812812
return BindParameterFromService(parameter, factoryContext);
813813
}
814-
else if (parameterCustomAttributes.OfType<FromKeyedServicesAttribute>().FirstOrDefault() is { } keyedServicesAttribute)
814+
else if (parameterCustomAttributes.FirstOrDefault(a => typeof(FromKeyedServicesAttribute).IsAssignableFrom(a.GetType())) is FromKeyedServicesAttribute keyedServicesAttribute)
815815
{
816816
if (factoryContext.ServiceProviderIsService is not IServiceProviderIsKeyedService)
817817
{

src/Mvc/Mvc.Abstractions/src/ModelBinding/BindingInfo.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ public Type? BinderType
177177
}
178178

179179
// Keyed services
180-
if (attributes.OfType<FromKeyedServicesAttribute>().FirstOrDefault() is { } fromKeyedServicesAttribute)
180+
if (attributes.FirstOrDefault(a => typeof(FromKeyedServicesAttribute).IsAssignableFrom(a.GetType())) is FromKeyedServicesAttribute fromKeyedServicesAttribute)
181181
{
182182
if (bindingInfo.BindingSource != null)
183183
{

src/Mvc/Mvc.Abstractions/test/ModelBinding/BindingInfoTest.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,4 +326,31 @@ public void GetBindingInfo_ThrowsWhenWithFromKeyedServicesAttributeAndIFromServi
326326
// Act and Assert
327327
Assert.Throws<NotSupportedException>(() => BindingInfo.GetBindingInfo(attributes, modelMetadata));
328328
}
329+
330+
[Fact]
331+
public void GetBindingInfo_WithDerivedFromKeyedServicesAttribute()
332+
{
333+
// Arrange
334+
var key = new object();
335+
var attributes = new object[]
336+
{
337+
new CustomFromKeyedServicesAttribute(key),
338+
};
339+
var modelType = typeof(Guid);
340+
var provider = new TestModelMetadataProvider();
341+
var modelMetadata = provider.GetMetadataForType(modelType);
342+
343+
// Act
344+
var bindingInfo = BindingInfo.GetBindingInfo(attributes, modelMetadata);
345+
346+
// Assert
347+
Assert.NotNull(bindingInfo);
348+
Assert.Same(BindingSource.Services, bindingInfo.BindingSource);
349+
Assert.Same(key, bindingInfo.ServiceKey);
350+
}
351+
352+
private class CustomFromKeyedServicesAttribute : FromKeyedServicesAttribute
353+
{
354+
public CustomFromKeyedServicesAttribute(object key) : base(key) { }
355+
}
329356
}

src/SignalR/server/Core/src/Internal/HubMethodDescriptor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ public HubMethodDescriptor(ObjectMethodExecutor methodExecutor, IServiceProvider
8888
markedParameter = true;
8989
MarkServiceParameter(index);
9090
}
91-
else if (attribute is FromKeyedServicesAttribute keyedServicesAttribute)
91+
else if (typeof(FromKeyedServicesAttribute).IsAssignableFrom(attribute.GetType()) && attribute is FromKeyedServicesAttribute keyedServicesAttribute)
9292
{
9393
ThrowIfMarked(markedParameter);
9494
markedParameter = true;

0 commit comments

Comments
 (0)