From 14d3f2bc9ba5e99efd249078556a3671142585cf Mon Sep 17 00:00:00 2001 From: BrennanConroy Date: Thu, 23 Mar 2017 14:38:31 -0700 Subject: [PATCH] Allow overridden methods on hubs (#334) Allow overridden methods on hubs --- .../HubEndPoint.cs | 11 +-- .../HubEndpointTests.cs | 92 +++++++++++++++++++ 2 files changed, 97 insertions(+), 6 deletions(-) diff --git a/src/Microsoft.AspNetCore.SignalR/HubEndPoint.cs b/src/Microsoft.AspNetCore.SignalR/HubEndPoint.cs index de5edc16c3..c1cf3fcab1 100644 --- a/src/Microsoft.AspNetCore.SignalR/HubEndPoint.cs +++ b/src/Microsoft.AspNetCore.SignalR/HubEndPoint.cs @@ -307,25 +307,24 @@ namespace Microsoft.AspNetCore.SignalR private void DiscoverHubMethods() { - var typeInfo = typeof(THub).GetTypeInfo(); - - foreach (var methodInfo in typeInfo.DeclaredMethods.Where(m => IsHubMethod(m))) + var hubType = typeof(THub); + foreach (var methodInfo in hubType.GetMethods().Where(m => IsHubMethod(m))) { var methodName = methodInfo.Name; if (_methods.ContainsKey(methodName)) { - throw new NotSupportedException($"Duplicate definitions of '{methodInfo.Name}'. Overloading is not supported."); + throw new NotSupportedException($"Duplicate definitions of '{methodName}'. Overloading is not supported."); } - var executor = ObjectMethodExecutor.Create(methodInfo, typeInfo); + var executor = ObjectMethodExecutor.Create(methodInfo, hubType.GetTypeInfo()); _methods[methodName] = new HubMethodDescriptor(executor); if (_logger.IsEnabled(LogLevel.Debug)) { _logger.LogDebug("Hub method '{methodName}' is bound", methodName); } - }; + } } private static bool IsHubMethod(MethodInfo methodInfo) diff --git a/test/Microsoft.AspNetCore.SignalR.Tests/HubEndpointTests.cs b/test/Microsoft.AspNetCore.SignalR.Tests/HubEndpointTests.cs index 703ed2865b..aeafe1a6fb 100644 --- a/test/Microsoft.AspNetCore.SignalR.Tests/HubEndpointTests.cs +++ b/test/Microsoft.AspNetCore.SignalR.Tests/HubEndpointTests.cs @@ -251,6 +251,50 @@ namespace Microsoft.AspNetCore.SignalR.Tests } } + [Fact] + public async Task CanCallInheritedHubMethodFromInheritingHub() + { + var serviceProvider = CreateServiceProvider(); + + var endPoint = serviceProvider.GetService>(); + + using (var client = new TestClient(serviceProvider)) + { + var endPointTask = endPoint.OnConnectedAsync(client.Connection); + + var result = await client.Invoke(nameof(InheritedHub.BaseMethod), "string").OrTimeout(); + + Assert.Equal("string", result.Result); + + // kill the connection + client.Dispose(); + + await endPointTask.OrTimeout(); + } + } + + [Fact] + public async Task CanCallOverridenVirtualHubMethod() + { + var serviceProvider = CreateServiceProvider(); + + var endPoint = serviceProvider.GetService>(); + + using (var client = new TestClient(serviceProvider)) + { + var endPointTask = endPoint.OnConnectedAsync(client.Connection); + + var result = await client.Invoke(nameof(InheritedHub.VirtualMethod), 10).OrTimeout(); + + Assert.Equal(0L, result.Result); + + // kill the connection + client.Dispose(); + + await endPointTask.OrTimeout(); + } + } + [Fact] public async Task CannotCallOverriddenBaseHubMethod() { @@ -273,6 +317,22 @@ namespace Microsoft.AspNetCore.SignalR.Tests } } + [Fact] + public void HubsCannotHaveOverloadedMethods() + { + var serviceProvider = CreateServiceProvider(); + + try + { + var endPoint = serviceProvider.GetService>(); + Assert.True(false); + } + catch (NotSupportedException ex) + { + Assert.Equal("Duplicate definitions of 'OverloadedMethod'. Overloading is not supported.", ex.Message); + } + } + [Fact] public async Task BroadcastHubMethod_SendsToAllClients() { @@ -546,6 +606,38 @@ namespace Microsoft.AspNetCore.SignalR.Tests } } + private class InheritedHub : BaseHub + { + public override int VirtualMethod(int num) + { + return num - 10; + } + } + + private class BaseHub : Hub + { + public string BaseMethod(string message) + { + return message; + } + + public virtual int VirtualMethod(int num) + { + return num; + } + } + + private class InvalidHub : Hub + { + public void OverloadedMethod(int num) + { + } + + public void OverloadedMethod(string message) + { + } + } + private class TestHub : Hub { private TrackDispose _trackDispose;