public async ValueTask BindFunctionInputAsync()

in src/DotNetWorker.Core/Context/Features/DefaultFunctionInputBindingFeature.cs [28:109]


        public async ValueTask<FunctionInputBindingResult> BindFunctionInputAsync(FunctionContext context)
        {
            ObjectDisposedThrowHelper.ThrowIf(_disposed, this);

            // Setting second parameter to CancellationToken.None to prevent a TaskCancelledException if the 
            // pipeline cancels the code before the function is invoked. This way the customer code will be invoked
            // and they can handle the cancellation token.
            await _semaphoreSlim.WaitAsync(WaitTimeInMilliSeconds, CancellationToken.None);

            try
            {
                if (_inputBindingResult is not null)
                {
                    // Return the cached value if BindFunctionInputAsync is called a second time during invocation.
                    return _inputBindingResult!;
                }

                IFunctionBindingsFeature functionBindings = context.GetBindings();
                var inputConversionFeature = context.Features.Get<IInputConversionFeature>()
                    ?? throw new InvalidOperationException("Input conversion feature is missing.");

                var parameterValues = new object?[context.FunctionDefinition.Parameters.Length];
                List<string>? errors = null;

                for (int i = 0; i < parameterValues.Length; i++)
                {
                    FunctionParameter parameter = context.FunctionDefinition.Parameters[i];

                    TryGetBindingSource(parameter.Name, functionBindings, out object? source);

                    ConversionResult bindingResult = await ConvertAsync(context, parameter, _converterContextFactory, inputConversionFeature, source);

                    if (bindingResult.Status == ConversionStatus.Succeeded)
                    {
                        parameterValues[i] = bindingResult.Value;
                    }
                    else if (bindingResult.Status == ConversionStatus.Failed && source is not null)
                    {
                        // Don't initialize this list unless we have to
                        errors ??= new List<string>();

                        errors.Add($"Cannot convert input parameter '{parameter.Name}' to type '{parameter.Type.FullName}' from type '{source.GetType().FullName}'. Error:{bindingResult.Error}");
                    }
                    else if (bindingResult.Status == ConversionStatus.Unhandled)
                    {
                        // If still unhandled after going through all converters,check an explicit default value was provided for the parameter.
                        if (parameter.HasDefaultValue)
                        {
                            parameterValues[i] = parameter.DefaultValue;
                        }
                        else if (parameter.IsReferenceOrNullableType)
                        {
                            // If the parameter is a reference type or nullable type, set it to null.
                            parameterValues[i] = null;
                        }
                        else
                        {
                            // Non nullable value type with no default value.
                            // We could not find a value for this param. should throw.
                            errors ??= new List<string>();
                            errors.Add(
                                $"Could not populate the value for '{parameter.Name}' parameter. Consider adding a default value or making the parameter nullable.");
                        }
                    }
                }

                // found errors
                if (errors is not null)
                {
                    throw new FunctionInputConverterException(
                        $"Error converting {errors.Count} input parameters for Function '{context.FunctionDefinition.Name}': {string.Join(Environment.NewLine, errors)}");
                }

                _inputBindingResult = new FunctionInputBindingResult(parameterValues);

                return _inputBindingResult;
            }
            finally
            {
                _semaphoreSlim.Release();
            }
        }