1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
using System;
using System.Reflection;
using System.Collections;
using System.Diagnostics;
using System.Workflow.ComponentModel;
using System.Workflow.Runtime;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
namespace System.Workflow.Activities
{
internal static class InvokeHelper
{
internal static void InitializeParameters(MethodInfo methodBase, WorkflowParameterBindingCollection parameterBindings)
{
ParameterInfo[] parameters = methodBase.GetParameters();
foreach (ParameterInfo parameter in parameters)
{
if (!parameterBindings.Contains(parameter.Name))
parameterBindings.Add(new WorkflowParameterBinding(parameter.Name));
}
if (methodBase.ReturnType != typeof(void))
{
if (!parameterBindings.Contains("(ReturnValue)"))
parameterBindings.Add(new WorkflowParameterBinding("(ReturnValue)"));
}
}
internal static object[] GetParameters(MethodBase methodBase, WorkflowParameterBindingCollection parameterBindings)
{
ParameterInfo[] formalParameters = methodBase.GetParameters();
object[] actualParameters = new object[formalParameters.Length];
int index = 0;
foreach (ParameterInfo formalParameter in formalParameters)
{
if (parameterBindings.Contains(formalParameter.Name))
{
WorkflowParameterBinding binding = parameterBindings[formalParameter.Name];
actualParameters[index] = binding.Value;
}
index++;
}
return actualParameters;
}
internal static object[] GetParameters(MethodBase methodBase, WorkflowParameterBindingCollection parameterBindings, out ParameterModifier[] parameterModifiers)
{
ParameterInfo[] formalParameters = methodBase.GetParameters();
object[] actualParameters = new object[formalParameters.Length];
if (actualParameters.Length == 0)
{
parameterModifiers = new ParameterModifier[0];
return actualParameters;
}
int index = 0;
BinaryFormatter formatter = null;
ParameterModifier parameterModifier = new ParameterModifier(actualParameters.Length);
foreach (ParameterInfo formalParameter in formalParameters)
{
if (formalParameter.ParameterType.IsByRef)
{
parameterModifier[index] = true;
}
else
{
parameterModifier[index] = false;
}
if (parameterBindings.Contains(formalParameter.Name))
{
WorkflowParameterBinding binding = parameterBindings[formalParameter.Name];
if (formatter == null)
formatter = new BinaryFormatter();
actualParameters[index] = CloneOutboundValue(binding.Value, formatter, formalParameter.Name);
}
index++;
}
parameterModifiers = new ParameterModifier[1] { parameterModifier };
return actualParameters;
}
internal static object CloneOutboundValue(object source, BinaryFormatter formatter, string name)
{
if (source == null || source.GetType().IsValueType)
return source;
ICloneable clone = source as ICloneable;
if (clone != null)
return clone.Clone();
System.IO.MemoryStream stream = new System.IO.MemoryStream(1024);
try
{
formatter.Serialize(stream, source);
}
catch (SerializationException e)
{
throw new InvalidOperationException(SR.GetString(SR.Error_CallExternalMethodArgsSerializationException, name), e);
}
stream.Position = 0;
object cloned = formatter.Deserialize(stream);
return cloned;
}
internal static void SaveOutRefParameters(object[] actualParameters, MethodBase methodBase, WorkflowParameterBindingCollection parameterBindings)
{
int index = 0;
BinaryFormatter formatter = null;
foreach (ParameterInfo formalParameter in methodBase.GetParameters())
{
if (parameterBindings.Contains(formalParameter.Name))
{
if (formalParameter.ParameterType.IsByRef || (formalParameter.IsIn && formalParameter.IsOut))
{
WorkflowParameterBinding binding = parameterBindings[formalParameter.Name];
if (formatter == null)
formatter = new BinaryFormatter();
binding.Value = CloneOutboundValue(actualParameters[index], formatter, formalParameter.Name);
}
}
index++;
}
}
}
}
|