Skip to content
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

Overload not supported exception details #1

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Contracts;
Expand All @@ -16,7 +16,7 @@ namespace SignalRNetClientProxyMapper
/// </summary>
public static class ClientHubProxyExtensions
{
static readonly MethodInfo InvokeReturnMethod = typeof (ClientHubProxyBase).GetMethod("InvokeReturn",
static readonly MethodInfo InvokeReturnMethod = typeof(ClientHubProxyBase).GetMethod("InvokeReturn",
BindingFlags.NonPublic | BindingFlags.Instance);
static readonly Regex HasInterfaceITest = new Regex("^[I]{1}[A-Z]{1}", RegexOptions.Compiled);

Expand All @@ -29,9 +29,10 @@ public static class ClientHubProxyExtensions
[SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0",
Justification = "@this is already validated by CodeContracts but is not picked up by Code Analysis")]
public static T CreateStrongHubProxy<T>(this HubConnection @this)
where T : class, IClientHubProxyBase {
where T : class, IClientHubProxyBase
{
Contract.Requires<ArgumentNullException>(@this != null);
Contract.Requires<InvalidCastException>(typeof (T).IsInterface, "The Proxy Type must be an Interface");
Contract.Requires<InvalidCastException>(typeof(T).IsInterface, "The Proxy Type must be an Interface");

return @this.CreateStrongHubProxy<T>(true);
}
Expand All @@ -50,9 +51,10 @@ public static T CreateStrongHubProxy<T>(this HubConnection @this)
Justification = "@this is already validated by CodeContracts but is not picked up by Code Analysis")]
// ReSharper disable once MemberCanBePrivate.Global
public static T CreateStrongHubProxy<T>(this HubConnection @this, bool dropInterfaceI)
where T : class, IClientHubProxyBase {
where T : class, IClientHubProxyBase
{
Contract.Requires<ArgumentNullException>(@this != null);
Contract.Requires<InvalidCastException>(typeof (T).IsInterface, "The Proxy Type must be an Interface");
Contract.Requires<InvalidCastException>(typeof(T).IsInterface, "The Proxy Type must be an Interface");

return default(T).GetStrongTypedClientProxy(@this.CreateHubProxy(GetHubName<T>(dropInterfaceI)));
}
Expand All @@ -69,14 +71,16 @@ public static T CreateStrongHubProxy<T>(this HubConnection @this, bool dropInter
[SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "this",
Justification = "@this is used to attach the extension method to the desired interface.")]
public static T GetStrongTypedClientProxy<T>(this T @this, IHubProxy hubProxy)
where T : class, IClientHubProxyBase {
Contract.Requires<InvalidCastException>(typeof (T).IsInterface, "The Proxy Type must be an Interface");
where T : class, IClientHubProxyBase
{
Contract.Requires<InvalidCastException>(typeof(T).IsInterface, "The Proxy Type must be an Interface");

var type = typeof (T);
var type = typeof(T);
dynamic proxy = new ClientHubProxyBase(hubProxy);

var methodInfos = GetMethods(type).Distinct().Where(x => !IsMappingDisabled(x));
foreach (var method in methodInfos) {
foreach (var method in methodInfos)
{
if (method.IsSpecialName &&
(method.Name.StartsWith("set_", StringComparison.Ordinal) ||
method.Name.StartsWith("get_", StringComparison.Ordinal)))
Expand All @@ -85,13 +89,14 @@ public static T GetStrongTypedClientProxy<T>(this T @this, IHubProxy hubProxy)
var returnType = method.ReturnType.IsGenericType
? method.ReturnType.GetGenericTypeDefinition()
: method.ReturnType;
if (returnType == typeof (Task))
if (returnType == typeof(Task))
MapReturnFunctions(proxy, method);
else if (returnType == typeof (Task<>))
else if (returnType == typeof(Task<>))
MapGenericReturnFunctions(proxy, method);
else if (returnType == typeof (IDisposable))
else if (returnType == typeof(IDisposable))
MapEventFunctions(proxy, method);
else {
else
{
throw new ArgumentException(
"Strong-Typed Methods must return a Task or Task<>, Events must return an IDisposable",
method.Name);
Expand All @@ -101,34 +106,39 @@ public static T GetStrongTypedClientProxy<T>(this T @this, IHubProxy hubProxy)
return Impromptu.ActLike<T>(proxy);
}

internal static IEnumerable<MethodInfo> GetMethods(Type type) {
foreach (var method in type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)) {
internal static IEnumerable<MethodInfo> GetMethods(Type type)
{
foreach (var method in type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly))
{
yield return method;
}
foreach (var method in type.GetInterfaces().SelectMany(GetMethods)) {
foreach (var method in type.GetInterfaces().SelectMany(GetMethods))
{
yield return method;
}
}

// ReSharper disable once MemberCanBePrivate.Global
internal static void MapEventFunctions(ClientHubProxyBase proxy, MethodInfo method) {
internal static void MapEventFunctions(ClientHubProxyBase proxy, MethodInfo method)
{
Contract.Requires<ArgumentOutOfRangeException>(method.GetParameters().Length <= 7,
"The Proxy mapper only supports events with up to 7 parameters");

var name = method.Name;
var hubName = GetHubMethodName(method);

if (proxy.ContainsKey(name))
throw new NotSupportedException("Overloading is not supported");
throw new NotSupportedException("Overloading is not supported. Please check for following method name in your client-server implementation:'" + name + "'");

proxy.Add(name,
(Func<dynamic, IDisposable>) (action => HubProxyExtensions.On(proxy.HubProxy, hubName, action)));
(Func<dynamic, IDisposable>)(action => HubProxyExtensions.On(proxy.HubProxy, hubName, action)));
}

[SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity",
Justification = "SignalR has built-in limitations we must comply with.")]
// ReSharper disable once MemberCanBePrivate.Global
internal static void MapGenericReturnFunctions(ClientHubProxyBase proxy, MethodInfo method) {
internal static void MapGenericReturnFunctions(ClientHubProxyBase proxy, MethodInfo method)
{
Contract.Requires<ArgumentOutOfRangeException>(method.GetParameters().Length <= 7,
"The Proxy mapper only supports methods with up to 7 parameters");

Expand All @@ -139,134 +149,140 @@ internal static void MapGenericReturnFunctions(ClientHubProxyBase proxy, MethodI
var hubName = GetHubMethodName(method);

if (proxy.ContainsKey(name))
throw new NotSupportedException("Overloading is not supported");
throw new NotSupportedException("Overloading is not supported. Please check for following method name in your client-server implementation:'" + name + "'");

switch (method.GetParameters().Length) {
case 0:
proxy.Add(name,
(Func<dynamic>) (() => invokeReturnInstance.Invoke(proxy, new object[] {hubName, new object[] {}})));
break;
case 1:
proxy.Add(name,
(Func<dynamic, dynamic>)
(arg1 => invokeReturnInstance.Invoke(proxy, new object[] {hubName, new object[] {arg1}})));
break;
case 2:
proxy.Add(name,
(Func<dynamic, dynamic, dynamic>)
((arg1, arg2) =>
invokeReturnInstance.Invoke(proxy, new object[] {hubName, new object[] {arg1, arg2}})));
break;
case 3:
proxy.Add(name,
(Func<dynamic, dynamic, dynamic, dynamic>)
((arg1, arg2, arg3) =>
invokeReturnInstance.Invoke(proxy, new object[] {hubName, new object[] {arg1, arg2, arg3}})));
break;
case 4:
proxy.Add(name,
(Func<dynamic, dynamic, dynamic, dynamic, dynamic>)
((arg1, arg2, arg3, arg4) =>
invokeReturnInstance.Invoke(proxy,
new object[] {hubName, new object[] {arg1, arg2, arg3, arg4}})));
break;
case 5:
proxy.Add(name,
(Func<dynamic, dynamic, dynamic, dynamic, dynamic, dynamic>)
((arg1, arg2, arg3, arg4, arg5) =>
invokeReturnInstance.Invoke(proxy,
new object[] {hubName, new object[] {arg1, arg2, arg3, arg4, arg5}})));
break;
case 6:
proxy.Add(name,
(Func<dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic>)
((arg1, arg2, arg3, arg4, arg5, arg6) =>
invokeReturnInstance.Invoke(proxy,
new object[] {hubName, new object[] {arg1, arg2, arg3, arg4, arg5, arg6}})));
break;
case 7:
proxy.Add(name,
(Func<dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic>)
((arg1, arg2, arg3, arg4, arg5, arg6, arg7) =>
invokeReturnInstance.Invoke(proxy,
new object[] {hubName, new object[] {arg1, arg2, arg3, arg4, arg5, arg6, arg7}})));
break;
switch (method.GetParameters().Length)
{
case 0:
proxy.Add(name,
(Func<dynamic>)(() => invokeReturnInstance.Invoke(proxy, new object[] { hubName, new object[] { } })));
break;
case 1:
proxy.Add(name,
(Func<dynamic, dynamic>)
(arg1 => invokeReturnInstance.Invoke(proxy, new object[] { hubName, new object[] { arg1 } })));
break;
case 2:
proxy.Add(name,
(Func<dynamic, dynamic, dynamic>)
((arg1, arg2) =>
invokeReturnInstance.Invoke(proxy, new object[] { hubName, new object[] { arg1, arg2 } })));
break;
case 3:
proxy.Add(name,
(Func<dynamic, dynamic, dynamic, dynamic>)
((arg1, arg2, arg3) =>
invokeReturnInstance.Invoke(proxy, new object[] { hubName, new object[] { arg1, arg2, arg3 } })));
break;
case 4:
proxy.Add(name,
(Func<dynamic, dynamic, dynamic, dynamic, dynamic>)
((arg1, arg2, arg3, arg4) =>
invokeReturnInstance.Invoke(proxy,
new object[] { hubName, new object[] { arg1, arg2, arg3, arg4 } })));
break;
case 5:
proxy.Add(name,
(Func<dynamic, dynamic, dynamic, dynamic, dynamic, dynamic>)
((arg1, arg2, arg3, arg4, arg5) =>
invokeReturnInstance.Invoke(proxy,
new object[] { hubName, new object[] { arg1, arg2, arg3, arg4, arg5 } })));
break;
case 6:
proxy.Add(name,
(Func<dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic>)
((arg1, arg2, arg3, arg4, arg5, arg6) =>
invokeReturnInstance.Invoke(proxy,
new object[] { hubName, new object[] { arg1, arg2, arg3, arg4, arg5, arg6 } })));
break;
case 7:
proxy.Add(name,
(Func<dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic>)
((arg1, arg2, arg3, arg4, arg5, arg6, arg7) =>
invokeReturnInstance.Invoke(proxy,
new object[] { hubName, new object[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7 } })));
break;
}
}

internal static bool IsMappingDisabled(MethodInfo method) {
internal static bool IsMappingDisabled(MethodInfo method)
{
return method.GetCustomAttribute<NotMappedAttribute>(false) != null;
}

// ReSharper disable once MemberCanBePrivate.Global
internal static string GetHubMethodName(MethodInfo method) {
internal static string GetHubMethodName(MethodInfo method)
{
var hubMethodNameAttribute = method.GetCustomAttribute<HubMethodNameAttribute>(false);
return hubMethodNameAttribute != null ? hubMethodNameAttribute.MethodName : method.Name;
}

internal static string GetHubName<T>(bool dropInterfaceI = true) {
var hubMethodNameAttribute = typeof (T).GetCustomAttribute<HubNameAttribute>(false);
internal static string GetHubName<T>(bool dropInterfaceI = true)
{
var hubMethodNameAttribute = typeof(T).GetCustomAttribute<HubNameAttribute>(false);

return hubMethodNameAttribute != null
? hubMethodNameAttribute.HubName
: ((dropInterfaceI && HasInterfaceITest.IsMatch(typeof (T).Name))
? typeof (T).Name.Remove(0, 1)
: typeof (T).Name);
: ((dropInterfaceI && HasInterfaceITest.IsMatch(typeof(T).Name))
? typeof(T).Name.Remove(0, 1)
: typeof(T).Name);
}

[SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity",
Justification = "SignalR has built-in limitations we must comply with.")]
// ReSharper disable once MemberCanBePrivate.Global
internal static void MapReturnFunctions(ClientHubProxyBase proxy, MethodInfo method) {
internal static void MapReturnFunctions(ClientHubProxyBase proxy, MethodInfo method)
{
Contract.Requires<ArgumentOutOfRangeException>(method.GetParameters().Length <= 10,
"The Proxy mapper only supports methods with up to 10 parameters");

var name = method.Name;
var hubName = GetHubMethodName(method);

if (proxy.ContainsKey(name))
throw new NotSupportedException("Overloading is not supported");
throw new NotSupportedException("Overloading is not supported. Please check for following method name in your client-server implementation:'" + name + "'");

switch (method.GetParameters().Length) {
case 0:
proxy.Add(name, (Func<dynamic>) (() => proxy.Invoke(hubName, new object[] {})));
break;
case 1:
proxy.Add(name, (Func<dynamic, dynamic>) (arg1 => proxy.Invoke(hubName, new object[] {arg1})));
break;
case 2:
proxy.Add(name,
(Func<dynamic, dynamic, dynamic>) ((arg1, arg2) => proxy.Invoke(hubName, new object[] {arg1, arg2})));
break;
case 3:
proxy.Add(name,
(Func<dynamic, dynamic, dynamic, dynamic>)
((arg1, arg2, arg3) => proxy.Invoke(hubName, new object[] {arg1, arg2, arg3})));
break;
case 4:
proxy.Add(name,
(Func<dynamic, dynamic, dynamic, dynamic, dynamic>)
((arg1, arg2, arg3, arg4) => proxy.Invoke(hubName, new object[] {arg1, arg2, arg3, arg4})));
break;
case 5:
proxy.Add(name,
(Func<dynamic, dynamic, dynamic, dynamic, dynamic, dynamic>)
((arg1, arg2, arg3, arg4, arg5) =>
proxy.Invoke(hubName, new object[] {arg1, arg2, arg3, arg4, arg5})));
break;
case 6:
proxy.Add(name,
(Func<dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic>)
((arg1, arg2, arg3, arg4, arg5, arg6) =>
proxy.Invoke(hubName, new object[] {arg1, arg2, arg3, arg4, arg5, arg6})));
break;
case 7:
proxy.Add(name,
(Func<dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic>)
((arg1, arg2, arg3, arg4, arg5, arg6, arg7) =>
proxy.Invoke(hubName, new object[] {arg1, arg2, arg3, arg4, arg5, arg6, arg7})));
break;
switch (method.GetParameters().Length)
{
case 0:
proxy.Add(name, (Func<dynamic>)(() => proxy.Invoke(hubName, new object[] { })));
break;
case 1:
proxy.Add(name, (Func<dynamic, dynamic>)(arg1 => proxy.Invoke(hubName, new object[] { arg1 })));
break;
case 2:
proxy.Add(name,
(Func<dynamic, dynamic, dynamic>)((arg1, arg2) => proxy.Invoke(hubName, new object[] { arg1, arg2 })));
break;
case 3:
proxy.Add(name,
(Func<dynamic, dynamic, dynamic, dynamic>)
((arg1, arg2, arg3) => proxy.Invoke(hubName, new object[] { arg1, arg2, arg3 })));
break;
case 4:
proxy.Add(name,
(Func<dynamic, dynamic, dynamic, dynamic, dynamic>)
((arg1, arg2, arg3, arg4) => proxy.Invoke(hubName, new object[] { arg1, arg2, arg3, arg4 })));
break;
case 5:
proxy.Add(name,
(Func<dynamic, dynamic, dynamic, dynamic, dynamic, dynamic>)
((arg1, arg2, arg3, arg4, arg5) =>
proxy.Invoke(hubName, new object[] { arg1, arg2, arg3, arg4, arg5 })));
break;
case 6:
proxy.Add(name,
(Func<dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic>)
((arg1, arg2, arg3, arg4, arg5, arg6) =>
proxy.Invoke(hubName, new object[] { arg1, arg2, arg3, arg4, arg5, arg6 })));
break;
case 7:
proxy.Add(name,
(Func<dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic>)
((arg1, arg2, arg3, arg4, arg5, arg6, arg7) =>
proxy.Invoke(hubName, new object[] { arg1, arg2, arg3, arg4, arg5, arg6, arg7 })));
break;
}
}
}
}
}