Skip to content

Commit

Permalink
IFromAttributeMetadata
Browse files Browse the repository at this point in the history
  • Loading branch information
BrennanConroy committed Jan 6, 2022
1 parent 3474e34 commit d0f7c41
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 53 deletions.
3 changes: 1 addition & 2 deletions src/SignalR/server/Core/src/Internal/DefaultHubDispatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -655,7 +655,6 @@ private void DiscoverHubMethods()
var hubName = hubType.Name;

using var scope = _serviceScopeFactory.CreateScope();
IServiceProviderIsService? serviceProviderIsService = scope.ServiceProvider.GetService<IServiceProviderIsService>();

foreach (var methodInfo in HubReflectionHelper.GetHubMethods(hubType))
{
Expand All @@ -675,7 +674,7 @@ private void DiscoverHubMethods()

var executor = ObjectMethodExecutor.Create(methodInfo, hubTypeInfo);
var authorizeAttributes = methodInfo.GetCustomAttributes<AuthorizeAttribute>(inherit: true);
_methods[methodName] = new HubMethodDescriptor(executor, serviceProviderIsService, authorizeAttributes);
_methods[methodName] = new HubMethodDescriptor(executor, authorizeAttributes);

Log.HubMethodBound(_logger, hubName, methodName);
}
Expand Down
10 changes: 5 additions & 5 deletions src/SignalR/server/Core/src/Internal/HubMethodDescriptor.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Threading.Channels;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http.Metadata;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Internal;

Expand All @@ -24,10 +24,10 @@ internal class HubMethodDescriptor

private readonly MethodInfo? _makeCancelableEnumeratorMethodInfo;
private Func<object, CancellationToken, IAsyncEnumerator<object>>? _makeCancelableEnumerator;
// bitset to store which parameters come from DI
private int _isServiceArgument;
// bitset to store which parameters come from DI
private int _isServiceArgument;

public HubMethodDescriptor(ObjectMethodExecutor methodExecutor, IServiceProviderIsService? serviceProviderIsService, IEnumerable<IAuthorizeData> policies)
public HubMethodDescriptor(ObjectMethodExecutor methodExecutor, IEnumerable<IAuthorizeData> policies)
{
MethodExecutor = methodExecutor;

Expand Down Expand Up @@ -79,7 +79,7 @@ public HubMethodDescriptor(ObjectMethodExecutor methodExecutor, IServiceProvider
HasSyntheticArguments = true;
return false;
}
else if (serviceProviderIsService?.IsService(p.ParameterType) == true)
else if (p.CustomAttributes.Any(a => typeof(IFromServiceMetadata).IsAssignableFrom(a.AttributeType)))
{
if (index >= 32)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Channels;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http.Metadata;
using Newtonsoft.Json.Serialization;

namespace Microsoft.AspNetCore.SignalR.Tests;
Expand Down Expand Up @@ -1246,50 +1242,58 @@ public void SetCaller(IClientProxy caller)
{
Caller = caller;
}
}

public class Service1
{ }
public class Service2
{ }
public class Service3
{ }
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = true)]
public class FromService : Attribute, IFromServiceMetadata
{ }
public class Service1
{ }
public class Service2
{ }
public class Service3
{ }

public class ServicesHub : TestHub
{
public bool SingleService([FromService] Service1 service)
{
return true;
}

public class ServicesHub : TestHub
public bool MultipleServices([FromService] Service1 service, [FromService] Service2 service2, [FromService] Service3 service3)
{
public bool SingleService(Service1 service)
{
return true;
}
return true;
}

public bool MultipleServices(Service1 service, Service2 service2, Service3 service3)
public async Task<int> ServicesAndParams(int value, [FromService] Service1 service, ChannelReader<int> channelReader, [FromService] Service2 service2, bool value2)
{
int total = 0;
while (await channelReader.WaitToReadAsync())
{
return true;
total += await channelReader.ReadAsync();
}
return total + value;
}

public async Task<int> ServicesAndParams(int value, Service1 service, ChannelReader<int> channelReader, Service2 service2, bool value2)
{
int total = 0;
while (await channelReader.WaitToReadAsync())
{
total += await channelReader.ReadAsync();
}
return total + value;
}
public int ServiceWithoutAttribute(Service1 service)
{
return 1;
}

public async Task Stream(ChannelReader<int> channelReader)
public async Task Stream(ChannelReader<int> channelReader)
{
while (await channelReader.WaitToReadAsync())
{
while (await channelReader.WaitToReadAsync())
{
await channelReader.ReadAsync();
}
await channelReader.ReadAsync();
}
}
}

public class TooManyParamsHub : Hub
{
public void ManyParams(int a, string b, bool c, float d, string e, int f, int g, int h, int i, int j, int k,
int l, int m, int n, int o, int p, int q, int r, int s, int t, int u, int v, int w, int x, int y, int z,
int aa, int ab, int ac, int ad, int ae, int af, Service1 service)
{ }
}
public class TooManyParamsHub : Hub
{
public void ManyParams(int a, string b, bool c, float d, string e, int f, int g, int h, int i, int j, int k,
int l, int m, int n, int o, int p, int q, int r, int s, int t, int u, int v, int w, int x, int y, int z,
int aa, int ab, int ac, int ad, int ae, int af, Service1 service)
{ }
}
28 changes: 21 additions & 7 deletions src/SignalR/server/SignalR/test/HubConnectionHandlerTests.cs
Original file line number Diff line number Diff line change
@@ -1,19 +1,13 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Buffers;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Pipelines;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading;
using System.Threading.Channels;
using System.Threading.Tasks;
using MessagePack;
using MessagePack.Formatters;
using MessagePack.Resolvers;
Expand All @@ -33,7 +27,6 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using Xunit;

namespace Microsoft.AspNetCore.SignalR.Tests;

Expand Down Expand Up @@ -4695,6 +4688,27 @@ public async Task StreamFromServiceDoesNotWork()
}
}

[Fact]
public async Task ServiceNotResolvedWithoutAttribute()
{
var serviceProvider = HubConnectionHandlerTestUtils.CreateServiceProvider(provider =>
{
provider.AddSignalR(options =>
{
options.EnableDetailedErrors = true;
});
provider.AddSingleton<Service1>();
});
var connectionHandler = serviceProvider.GetService<HubConnectionHandler<ServicesHub>>();

using (var client = new TestClient())
{
var connectionHandlerTask = await client.ConnectAsync(connectionHandler).DefaultTimeout();
var res = await client.InvokeAsync(nameof(ServicesHub.ServiceWithoutAttribute)).DefaultTimeout();
Assert.Equal("Failed to invoke 'ServiceWithoutAttribute' due to an error on the server. InvalidDataException: Invocation provides 0 argument(s) but target expects 1.", res.Error);
}
}

[Fact]
public void TooManyParametersWithServiceThrows()
{
Expand Down

0 comments on commit d0f7c41

Please sign in to comment.