private void SetInputBindingParameterValues(
            AzFunctionInfo functionInfo,
            IEnumerable <ParameterBinding> inputData,
            DurableController durableController,
            Hashtable triggerMetadata,
            TraceContext traceContext)
        {
            foreach (var binding in inputData)
            {
                if (functionInfo.FuncParameters.TryGetValue(binding.Name, out var paramInfo))
                {
                    if (!durableController.TryGetInputBindingParameterValue(binding.Name, out var valueToUse))
                    {
                        var bindingInfo = functionInfo.InputBindings[binding.Name];
                        valueToUse = Utils.TransformInBindingValueAsNeeded(paramInfo, bindingInfo, binding.Data.ToObject());
                    }

                    _pwsh.AddParameter(binding.Name, valueToUse);
                }
            }

            // Gives access to additional Trigger Metadata if the user specifies TriggerMetadata
            if (functionInfo.HasTriggerMetadataParam)
            {
                _pwsh.AddParameter(AzFunctionInfo.TriggerMetadata, triggerMetadata);
            }

            if (functionInfo.HasTraceContextParam)
            {
                _pwsh.AddParameter(AzFunctionInfo.TraceContext, traceContext);
            }
        }
        /// <summary>
        /// Execution a function fired by a trigger or an activity function scheduled by an orchestration.
        /// </summary>
        private Hashtable InvokeNonOrchestrationFunction(DurableController durableController, IDictionary outputBindings)
        {
            var pipelineItems = _pwsh.InvokeAndClearCommands <object>();
            var result        = new Hashtable(outputBindings, StringComparer.OrdinalIgnoreCase);

            durableController.AddPipelineOutputIfNecessary(pipelineItems, result);
            return(result);
        }
        public Hashtable InvokeFunction(
            AzFunctionInfo functionInfo,
            Hashtable triggerMetadata,
            TraceContext traceContext,
            RetryContext retryContext,
            IList <ParameterBinding> inputData,
            FunctionInvocationPerformanceStopwatch stopwatch)
        {
            var outputBindings = FunctionMetadata.GetOutputBindingHashtable(_pwsh.Runspace.InstanceId);

            var durableController = new DurableController(functionInfo.DurableFunctionInfo, _pwsh);

            try
            {
                durableController.BeforeFunctionInvocation(inputData);

                AddEntryPointInvocationCommand(functionInfo);
                stopwatch.OnCheckpoint(FunctionInvocationPerformanceStopwatch.Checkpoint.FunctionCodeReady);

                SetInputBindingParameterValues(functionInfo, inputData, durableController, triggerMetadata, traceContext, retryContext);
                stopwatch.OnCheckpoint(FunctionInvocationPerformanceStopwatch.Checkpoint.InputBindingValuesReady);

                if (!durableController.ShouldSuppressPipelineTraces())
                {
                    _pwsh.AddCommand("Microsoft.Azure.Functions.PowerShellWorker\\Trace-PipelineObject");
                }

                stopwatch.OnCheckpoint(FunctionInvocationPerformanceStopwatch.Checkpoint.InvokingFunctionCode);
                Logger.Log(isUserOnlyLog: false, LogLevel.Trace, CreateInvocationPerformanceReportMessage(functionInfo.FuncName, stopwatch));

                try
                {
                    return(durableController.TryInvokeOrchestrationFunction(out var result)
                                ? result
                                : InvokeNonOrchestrationFunction(durableController, outputBindings));
                }
                catch (RuntimeException e)
                {
                    ErrorAnalysisLogger.Log(Logger, e.ErrorRecord, isException: true);
                    Logger.Log(isUserOnlyLog: true, LogLevel.Error, GetFunctionExceptionMessage(e));
                    throw;
                }
                catch (OrchestrationFailureException e)
                {
                    if (e.InnerException is IContainsErrorRecord inner)
                    {
                        Logger.Log(isUserOnlyLog: true, LogLevel.Error, GetFunctionExceptionMessage(inner));
                    }
                    throw;
                }
            }
            finally
            {
                durableController.AfterFunctionInvocation();
                outputBindings.Clear();
                ResetRunspace();
            }
        }