Skip to content

Commit

Permalink
Fix contract methods which use out parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
mconnew authored and StephenBonikowsky committed Nov 4, 2019
1 parent 51aac76 commit 21b64d4
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,16 @@

using System.Diagnostics.Contracts;
using System.Reflection;
using System.Runtime;
using System.ServiceModel.Description;

namespace System.ServiceModel.Channels
{
// MethodCall associates a MethodBase with the arguments to pass to it.
internal class MethodCall
{
private object[] _inArgs;

public MethodCall(object[] args)
{
Contract.Assert(args != null);
Expand All @@ -21,10 +25,44 @@ public MethodCall(MethodBase methodBase, object[] args) : this(args)
{
Contract.Assert(methodBase != null);
MethodBase = methodBase;
CreateInArgs();
}

public MethodBase MethodBase { get; private set; }

public object[] Args { get; private set; }

public object[] InArgs => _inArgs ?? Args;

private void CreateInArgs()
{
var parameters = MethodBase.GetParameters();
int inCount = 0;
foreach(var param in parameters)
{
if (ServiceReflector.FlowsIn(param))
{
inCount++;
}
}

if (inCount == Args.Length) // All parameters are InArgs so do nothing and fallback to returning Args
{
return;
}

_inArgs = new object[inCount];
int inPos = 0;
for(int argPos = 0; argPos < parameters.Length; argPos++)
{
if (ServiceReflector.FlowsIn(parameters[argPos]))
{
_inArgs[inPos] = Args[argPos];
inPos++;
}
}

Fx.Assert((inPos - 1) != (inCount), $"Incorrect number of arguments put into _inArgs array, expected {inCount} and copied {inPos - 1}");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -164,9 +164,9 @@ public static Task CreateTask(ServiceChannel channel, MethodCall methodCall, Pro
{
if (operation.TaskTResult == ServiceReflector.VoidType)
{
return TaskCreator.CreateTask(channel, operation, methodCall.Args);
return TaskCreator.CreateTask(channel, operation, methodCall.InArgs);
}
return TaskCreator.CreateGenericTask(channel, operation, methodCall.Args);
return TaskCreator.CreateGenericTask(channel, operation, methodCall.InArgs);
}

private static Task CreateGenericTask(ServiceChannel channel, ProxyOperationRuntime operation, object[] inputParameters)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

namespace System.ServiceModel.Description
{
[DebuggerDisplay("Name={_name}, Namespace={_ns}, Type={Type}, Index={_index}}")]
[DebuggerDisplay("Name={XmlName}, Namespace={Namespace}, Type={Type}, Index={Index}}")]
public class MessagePartDescription
{
private ProtectionLevel _protectionLevel;
Expand All @@ -22,14 +22,14 @@ public MessagePartDescription(string name, string ns)
{
if (name == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("name", SR.SFxParameterNameCannotBeNull);
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(name), SR.SFxParameterNameCannotBeNull);
}

XmlName = new XmlName(name, true /*isEncoded*/);

if (!string.IsNullOrEmpty(ns))
{
NamingHelper.CheckUriParameter(ns, "ns");
NamingHelper.CheckUriParameter(ns, nameof(ns));
}

Namespace = ns;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ internal object[] MapSyncInputs(MethodCall methodCall, out object[] outs)
return Array.Empty<object>();
}

return methodCall.Args;
return methodCall.InArgs;
}

internal object[] MapAsyncBeginInputs(MethodCall methodCall, out AsyncCallback callback, out object asyncState)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,9 @@ public interface IServiceContractUniqueTypeOutSyncService
{
[OperationContract]
void Request(string stringRequest, out UniqueType uniqueTypeResponse);

[OperationContract]
void Request2(out UniqueType uniqueTypeResponse, string stringRequest);
}

[ServiceContract]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,14 @@ public static void ServiceContract_TypedProxy_SyncOperation_UniqueTypeOutArg()
// *** EXECUTE *** \\
serviceProxy.Request(message, out uniqueType);

// *** VALIDATE *** \\
Assert.True((uniqueType.stringValue == message),
String.Format("The value of the 'stringValue' field in the UniqueType instance was not as expected. expected {0} but got {1}", message, uniqueType.stringValue));

// *** EXECUTE *** \\
uniqueType = null;
serviceProxy.Request2(out uniqueType, message);

// *** VALIDATE *** \\
Assert.True((uniqueType.stringValue == message),
String.Format("The value of the 'stringValue' field in the UniqueType instance was not as expected. expected {0} but got {1}", message, uniqueType.stringValue));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ public interface IServiceContractUniqueTypeOutSyncService
{
[OperationContract]
void Request(string stringRequest, out UniqueType uniqueTypeResponse);

[OperationContract]
void Request2(out UniqueType uniqueTypeResponse, string stringRequest);
}

[ServiceContract]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ public void Request(string stringRequest, out UniqueType uniqueTypeResponse)
uniqueTypeResponse = new UniqueType();
uniqueTypeResponse.stringValue = stringRequest;
}

public void Request2(out UniqueType uniqueTypeResponse, string stringRequest)
{
uniqueTypeResponse = new UniqueType();
uniqueTypeResponse.stringValue = stringRequest;
}
}

public class ServiceContractUniqueTypeRefSyncService : IServiceContractUniqueTypeRefSyncService
Expand Down

0 comments on commit 21b64d4

Please sign in to comment.