void LoadOutputParametersIntoArray(ParameterInfo[] parameters, LocalBuilder[] parameterLocals, ArgBuilder outputParametersArg, out int outputParameterCount) { outputParameterCount = 0; for (int i = 0; i < parameterLocals.Length; i++) { if (ServiceReflector.FlowsOut(parameters[i])) { ilg.Load(outputParametersArg); ilg.Load(outputParameterCount); ilg.Load(parameterLocals[i]); ilg.ConvertValue(parameterLocals[i].LocalType, TypeOfObject); ilg.Stelem(TypeOfObject); outputParameterCount++; } } }
internal static InvokeDelegate GenerateInvokeDelegate(MethodInfo method, out int inputParameterCount, out int outputParameterCount) { ParameterInfo[] parameters = method.GetParameters(); bool returnsValue = method.ReturnType != typeof(void); int paramCount = parameters.Length; var inputParamPositions = new List <int>(); var outputParamPositions = new List <int>(); for (int i = 0; i < parameters.Length; i++) { if (ServiceReflector.FlowsIn(parameters[i])) { inputParamPositions.Add(i); } if (ServiceReflector.FlowsOut(parameters[i])) { outputParamPositions.Add(i); } } int[] inputPos = inputParamPositions.ToArray(); int[] outputPos = outputParamPositions.ToArray(); inputParameterCount = inputPos.Length; outputParameterCount = outputPos.Length; // TODO: Replace with expression to remove performance cost of calling delegate.Invoke. InvokeDelegate lambda = delegate(object target, object[] inputs, object[] outputs) { object[] paramsLocal = null; if (paramCount > 0) { paramsLocal = new object[paramCount]; for (int i = 0; i < inputPos.Length; i++) { paramsLocal[inputPos[i]] = inputs[i]; } } object result = null; try { if (returnsValue) { result = method.Invoke(target, paramsLocal); } else { method.Invoke(target, paramsLocal); } } catch (TargetInvocationException tie) { ExceptionDispatchInfo.Capture(tie.InnerException).Throw(); } for (int i = 0; i < outputPos.Length; i++) { Debug.Assert(paramsLocal != null); outputs[i] = paramsLocal[outputPos[i]]; } return(result); }; return(lambda); }