Skip to content

Commit 17bee1b

Browse files
author
Péter Trombitás
committed
Support different TResult and TProgress with reflection-based callee (#353)
1 parent 0e9bf5f commit 17bee1b

File tree

3 files changed

+29
-58
lines changed

3 files changed

+29
-58
lines changed

src/netstandard/WampSharp/WAMP2/V2/Rpc/Callee/Reflection/MethodInfoValidation.cs

Lines changed: 4 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,6 @@ public static void ValidateProgressiveMethod(MethodInfo method)
104104
{
105105
ValidateAsyncMethod(method);
106106

107-
Type returnType =
108-
TaskExtensions.UnwrapReturnType(method.ReturnType);
109-
110107
ParameterInfo[] parameters = method.GetParameters();
111108
ParameterInfo lastParameter = parameters.LastOrDefault();
112109
ParameterInfo progressParameter = lastParameter;
@@ -118,41 +115,9 @@ public static void ValidateProgressiveMethod(MethodInfo method)
118115
parameters.Take(parameters.Length - 1).LastOrDefault();
119116
}
120117

121-
Type expectedParameterType =
122-
typeof(IProgress<>).MakeGenericType(returnType);
123-
124-
if ((progressParameter == null) || (progressParameter.ParameterType != expectedParameterType))
125-
{
126-
ThrowHelper.ProgressiveParameterTypeMismatch(method, returnType);
127-
}
128-
129-
ValidateTupleReturnTypeOfProgressiveMethod(method, progressParameter);
130-
}
131-
132-
private static void ValidateTupleReturnTypeOfProgressiveMethod(MethodInfo method, ParameterInfo lastParameter)
133-
{
134-
TupleElementNamesAttribute methodAttribute =
135-
method.ReturnParameter.GetCustomAttribute<TupleElementNamesAttribute>();
136-
137-
TupleElementNamesAttribute parameterAttribute =
138-
lastParameter.GetCustomAttribute<TupleElementNamesAttribute>();
139-
140-
bool methodHasAttribute = methodAttribute != null;
141-
bool parameterHasAttributte = parameterAttribute != null;
142-
143-
bool attributesMatch = methodHasAttribute == parameterHasAttributte;
144-
145-
if (methodHasAttribute && parameterHasAttributte)
146-
{
147-
IList<string> methodTransformNames = methodAttribute.TransformNames;
148-
IList<string> parameterTransformNames = parameterAttribute.TransformNames;
149-
150-
attributesMatch = methodTransformNames.SequenceEqual(parameterTransformNames);
151-
}
152-
153-
if (!attributesMatch)
118+
if ((progressParameter == null) || (progressParameter.ParameterType.GetGenericTypeDefinition() != typeof(IProgress<>)))
154119
{
155-
ThrowHelper.ProgressiveParameterTupleMismatch(method);
120+
ThrowHelper.ProgressiveParameterTypeMismatch(method);
156121
}
157122
}
158123

@@ -164,10 +129,10 @@ public static void AsyncOutRefMethod(MethodInfo method)
164129
($"Method {method.Name} of type {method.DeclaringType.FullName} is declared as a WAMP procedure, but it is both asynchronous and has out/ref parameters");
165130
}
166131

167-
public static void ProgressiveParameterTypeMismatch(MethodInfo method, Type returnType)
132+
public static void ProgressiveParameterTypeMismatch(MethodInfo method)
168133
{
169134
throw new ArgumentException
170-
($"Method {method.Name} of type {method.DeclaringType.FullName} is declared as a progressive WAMP procedure, but its last (or second to last) parameter is not a IProgress of its return type. Expected: IProgress<{returnType.FullName}>");
135+
($"Method {method.Name} of type {method.DeclaringType.FullName} is declared as a progressive WAMP procedure, but its last (or second to last) parameter is not an IProgress<TProgress>");
171136
}
172137

173138
public static void ObservableMethodNotDeclaredProgressive(MethodInfo method)
@@ -176,12 +141,6 @@ public static void ObservableMethodNotDeclaredProgressive(MethodInfo method)
176141
($"Method {method.Name} of type {method.DeclaringType.FullName} is returning an IObservable and therefore is required to be declared as a progressive WAMP procedure, but it is not. Please use the [WampProgressiveResultProcedure] attribute.");
177142
}
178143

179-
public static void ProgressiveParameterTupleMismatch(MethodInfo method)
180-
{
181-
throw new ArgumentException
182-
($"Method {method.Name} of type {method.DeclaringType.FullName} is declared as a progressive WAMP procedure that returns a tuple, but its last parameter tuple definition does not match its return type tuple definition.");
183-
}
184-
185144
public static void InvalidTupleReturnType(MethodInfo method)
186145
{
187146
throw new ArgumentException

src/netstandard/WampSharp/WAMP2/V2/Rpc/Callee/Reflection/OperationExtractor.cs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Linq;
34
using System.Reflection;
5+
using System.Threading;
46
using System.Threading.Tasks;
57
using WampSharp.V2.Core.Contracts;
68
using TaskExtensions = WampSharp.Core.Utilities.TaskExtensions;
@@ -62,14 +64,14 @@ protected IWampRpcOperation CreateRpcMethod(Func<object> instanceProvider, ICall
6264
MethodInfoValidation.ValidateProgressiveObservableMethod(method);
6365
return CreateProgressiveObservableOperation(instanceProvider, method, procedureUri);
6466
}
65-
else if (!typeof (Task).IsAssignableFrom(method.ReturnType))
67+
else if (!typeof(Task).IsAssignableFrom(method.ReturnType))
6668
{
6769
MethodInfoValidation.ValidateSyncMethod(method);
6870
return new SyncMethodInfoRpcOperation(instanceProvider, method, procedureUri);
6971
}
7072
else
7173
{
72-
if (method.IsDefined(typeof (WampProgressiveResultProcedureAttribute)))
74+
if (method.IsDefined(typeof(WampProgressiveResultProcedureAttribute)))
7375
{
7476
MethodInfoValidation.ValidateProgressiveMethod(method);
7577
return CreateProgressiveOperation(instanceProvider, method, procedureUri);
@@ -89,13 +91,23 @@ private static IWampRpcOperation CreateProgressiveOperation(Func<object> instanc
8991

9092
Type returnType =
9193
TaskExtensions.UnwrapReturnType(method.ReturnType);
94+
ParameterInfo[] parameters = method.GetParameters();
95+
ParameterInfo lastParameter = parameters.LastOrDefault();
96+
ParameterInfo progressParameter = lastParameter;
97+
98+
if ((lastParameter != null) &&
99+
(lastParameter.ParameterType == typeof(CancellationToken)))
100+
{
101+
progressParameter =
102+
parameters.Take(parameters.Length - 1).LastOrDefault();
103+
}
92104

93105
Type operationType =
94-
typeof (ProgressiveAsyncMethodInfoRpcOperation<>)
95-
.MakeGenericType(returnType);
106+
typeof(ProgressiveAsyncMethodInfoRpcOperation<,>)
107+
.MakeGenericType(returnType, progressParameter.ParameterType.GetGenericArguments().First());
96108

97109
IWampRpcOperation operation =
98-
(IWampRpcOperation) Activator.CreateInstance(operationType,
110+
(IWampRpcOperation)Activator.CreateInstance(operationType,
99111
instanceProvider,
100112
method,
101113
procedureUri);

src/netstandard/WampSharp/WAMP2/V2/Rpc/Callee/Reflection/ProgressiveAsyncMethodInfoRpcOperation.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,17 @@
33
using System.Linq;
44
using System.Reflection;
55
using System.Threading;
6-
using WampSharp.Core.Utilities;
76
using WampSharp.Core.Serialization;
7+
using WampSharp.Core.Utilities;
88
using WampSharp.V2.Core.Contracts;
99

1010
namespace WampSharp.V2.Rpc
1111
{
12-
public class ProgressiveAsyncMethodInfoRpcOperation<T> : AsyncMethodInfoRpcOperation
12+
public class ProgressiveAsyncMethodInfoRpcOperation<TResult, TProgress> : AsyncMethodInfoRpcOperation
1313
{
1414
private readonly RpcParameter[] mRpcParameters;
1515

16-
public ProgressiveAsyncMethodInfoRpcOperation(Func<object> instanceProvider, MethodInfo method, string procedureName) :
16+
public ProgressiveAsyncMethodInfoRpcOperation(Func<object> instanceProvider, MethodInfo method, string procedureName) :
1717
base(instanceProvider, method, procedureName)
1818
{
1919
RpcParameter[] baseParameters = base.Parameters;
@@ -45,21 +45,21 @@ protected override object[] GetMethodParameters<TMessage>(IWampRawRpcOperationRo
4545

4646
public override RpcParameter[] Parameters => mRpcParameters;
4747

48-
private class CallerProgress : IProgress<T>
48+
private class CallerProgress : IProgress<TProgress>
4949
{
5050
private readonly IWampRawRpcOperationRouterCallback mCaller;
51-
private readonly ProgressiveAsyncMethodInfoRpcOperation<T> mParent;
51+
private readonly ProgressiveAsyncMethodInfoRpcOperation<TResult, TProgress> mParent;
5252

5353
public CallerProgress(IWampRawRpcOperationRouterCallback caller,
54-
ProgressiveAsyncMethodInfoRpcOperation<T> parent)
54+
ProgressiveAsyncMethodInfoRpcOperation<TResult, TProgress> parent)
5555
{
5656
mCaller = caller;
5757
mParent = parent;
5858
}
5959

60-
public void Report(T value)
60+
public void Report(TProgress value)
6161
{
62-
mParent.CallResult(mCaller, value, new YieldOptions() {Progress = true});
62+
mParent.CallResult(mCaller, value, new YieldOptions() { Progress = true });
6363
}
6464
}
6565
}

0 commit comments

Comments
 (0)