예제 #1
0
        protected override Collection <ParameterDescriptor> GetFunctionParameters(IFunctionInvoker functionInvoker, FunctionMetadata functionMetadata,
                                                                                  BindingMetadata triggerMetadata, Collection <CustomAttributeBuilder> methodAttributes, Collection <FunctionBinding> inputBindings, Collection <FunctionBinding> outputBindings)
        {
            if (functionInvoker == null)
            {
                throw new ArgumentNullException("functionInvoker");
            }
            if (functionMetadata == null)
            {
                throw new ArgumentNullException("functionMetadata");
            }
            if (triggerMetadata == null)
            {
                throw new ArgumentNullException("triggerMetadata");
            }
            if (methodAttributes == null)
            {
                throw new ArgumentNullException("methodAttributes");
            }

            var dotNetInvoker = functionInvoker as DotNetFunctionInvoker;

            if (dotNetInvoker == null)
            {
                throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Expected invoker of type '{0}' but received '{1}'", typeof(DotNetFunctionInvoker).Name, functionInvoker.GetType().Name));
            }

            try
            {
                ApplyMethodLevelAttributes(functionMetadata, triggerMetadata, methodAttributes);

                MethodInfo      functionTarget = dotNetInvoker.GetFunctionTargetAsync().Result;
                ParameterInfo[] parameters     = functionTarget.GetParameters();
                Collection <ParameterDescriptor> descriptors = new Collection <ParameterDescriptor>();
                IEnumerable <FunctionBinding>    bindings    = inputBindings.Union(outputBindings);
                ParameterDescriptor descriptor = null;
                foreach (var parameter in parameters)
                {
                    // Is it the trigger parameter?
                    if (string.Compare(parameter.Name, triggerMetadata.Name, StringComparison.Ordinal) == 0)
                    {
                        ParameterDescriptor triggerParameter = CreateTriggerParameter(triggerMetadata, parameter.ParameterType);
                        descriptors.Add(triggerParameter);
                    }
                    else
                    {
                        Type parameterType    = parameter.ParameterType;
                        bool parameterIsByRef = parameterType.IsByRef;
                        if (parameterIsByRef)
                        {
                            parameterType = parameterType.GetElementType();
                        }

                        descriptor = new ParameterDescriptor(parameter.Name, parameter.ParameterType);
                        var binding = bindings.FirstOrDefault(b => string.Compare(b.Metadata.Name, parameter.Name, StringComparison.Ordinal) == 0);
                        if (binding != null)
                        {
                            Collection <CustomAttributeBuilder> customAttributes = binding.GetCustomAttributes(parameter.ParameterType);
                            if (customAttributes != null)
                            {
                                foreach (var customAttribute in customAttributes)
                                {
                                    descriptor.CustomAttributes.Add(customAttribute);
                                }
                            }
                        }

                        // In the C# programming model, IsOut is set for out parameters
                        // In the F# programming model, neither IsOut nor IsIn are set for byref parameters (which are used as out parameters).
                        //   Justification for this cariation of the programming model is that declaring 'out' parameters is (deliberately)
                        //   awkward in F#, they require opening System.Runtime.InteropServices and adding the [<Out>] attribute, and using
                        //   a byref parameter. In contrast declaring a byref parameter alone (neither labelled In nor Out) is simple enough.
                        if (parameter.IsOut || (functionMetadata.ScriptType == ScriptType.FSharp && parameterIsByRef && !parameter.IsIn))
                        {
                            descriptor.Attributes |= ParameterAttributes.Out;
                        }

                        descriptors.Add(descriptor);
                    }
                }

                // Add any additional required System parameters (if they haven't already been defined by the user)
                if (!descriptors.Any(p => p.Type == typeof(ExecutionContext)))
                {
                    // Add ExecutionContext to provide access to InvocationId, etc.
                    descriptors.Add(new ParameterDescriptor(ScriptConstants.SystemExecutionContextParameterName, typeof(ExecutionContext)));
                }

                if (TryCreateReturnValueParameterDescriptor(functionTarget.ReturnType, bindings, out descriptor))
                {
                    // If a return value binding has been specified, set up an output
                    // binding to map it to. By convention, this is set up as the last
                    // parameter.
                    descriptors.Add(descriptor);
                }

                return(descriptors);
            }
            catch (AggregateException exc)
            {
                if (!(exc.InnerException is CompilationErrorException))
                {
                    throw;
                }
            }
            catch (CompilationErrorException)
            {
            }

            // We were unable to compile the function to get its signature,
            // setup the descriptor with the default parameters
            methodAttributes.Clear();
            return(base.GetFunctionParameters(functionInvoker, functionMetadata, triggerMetadata, methodAttributes, inputBindings, outputBindings));
        }
        protected override Collection<ParameterDescriptor> GetFunctionParameters(IFunctionInvoker functionInvoker, FunctionMetadata functionMetadata,
            BindingMetadata triggerMetadata, Collection<CustomAttributeBuilder> methodAttributes, Collection<FunctionBinding> inputBindings, Collection<FunctionBinding> outputBindings)
        {
            if (functionInvoker == null)
            {
                throw new ArgumentNullException("functionInvoker");
            }
            if (functionMetadata == null)
            {
                throw new ArgumentNullException("functionMetadata");
            }
            if (triggerMetadata == null)
            {
                throw new ArgumentNullException("triggerMetadata");
            }
            if (methodAttributes == null)
            {
                throw new ArgumentNullException("methodAttributes");
            }

            var csharpInvoker = functionInvoker as CSharpFunctionInvoker;
            if (csharpInvoker == null)
            {
                throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Expected invoker of type '{0}' but received '{1}'", typeof(CSharpFunctionInvoker).Name, functionInvoker.GetType().Name));
            }

            try
            {
                ApplyMethodLevelAttributes(functionMetadata, triggerMetadata, methodAttributes);

                MethodInfo functionTarget = csharpInvoker.GetFunctionTargetAsync().Result;
                ParameterInfo[] parameters = functionTarget.GetParameters();
                Collection<ParameterDescriptor> descriptors = new Collection<ParameterDescriptor>();
                IEnumerable<FunctionBinding> bindings = inputBindings.Union(outputBindings);
                bool addHttpRequestSystemParameter = false;
                foreach (var parameter in parameters)
                {
                    // Is it the trigger parameter?
                    if (string.Compare(parameter.Name, triggerMetadata.Name, StringComparison.Ordinal) == 0)
                    {
                        descriptors.Add(CreateTriggerParameterDescriptor(parameter, triggerMetadata));

                        if (triggerMetadata.Type == BindingType.HttpTrigger && 
                            parameter.ParameterType != typeof(HttpRequestMessage))
                        {
                            addHttpRequestSystemParameter = true;
                        }
                    }
                    else
                    {
                        Type parameterType = parameter.ParameterType;
                        if (parameterType.IsByRef)
                        {
                            parameterType = parameterType.GetElementType();
                        }

                        var descriptor = new ParameterDescriptor(parameter.Name, parameter.ParameterType);
                        var binding = bindings.FirstOrDefault(b => string.Compare(b.Metadata.Name, parameter.Name, StringComparison.Ordinal) == 0);
                        if (binding != null)
                        {
                            Collection<CustomAttributeBuilder> customAttributes = binding.GetCustomAttributes();
                            if (customAttributes != null)
                            {
                                foreach (var customAttribute in customAttributes)
                                {
                                    descriptor.CustomAttributes.Add(customAttribute);
                                }
                            }
                        }

                        if (parameter.IsOut)
                        {
                            descriptor.Attributes |= ParameterAttributes.Out;
                        }

                        descriptors.Add(descriptor);
                    }
                }

                // Add any additional common System parameters
                // Add ExecutionContext to provide access to InvocationId, etc.
                descriptors.Add(new ParameterDescriptor("context", typeof(ExecutionContext)));
                
                // If we have an HTTP trigger binding but we're not binding
                // to the HttpRequestMessage, require it as a system parameter
                if (addHttpRequestSystemParameter)
                {
                    descriptors.Add(new ParameterDescriptor(ScriptConstants.DefaultSystemTriggerParameterName, typeof(HttpRequestMessage)));
                }

                return descriptors;
            }
            catch (AggregateException exc)
            {
                if (!(exc.InnerException is CompilationErrorException))
                {
                    throw;
                }
            }
            catch (CompilationErrorException)
            {
            }

            // We were unable to compile the function to get its signature,
            // setup the descriptor with the default parameters
            return base.GetFunctionParameters(functionInvoker, functionMetadata, triggerMetadata, methodAttributes, inputBindings, outputBindings);
        }
        protected override Collection <ParameterDescriptor> GetFunctionParameters(IFunctionInvoker functionInvoker, FunctionMetadata functionMetadata,
                                                                                  BindingMetadata triggerMetadata, Collection <CustomAttributeBuilder> methodAttributes, Collection <FunctionBinding> inputBindings, Collection <FunctionBinding> outputBindings)
        {
            if (functionInvoker == null)
            {
                throw new ArgumentNullException("functionInvoker");
            }
            if (functionMetadata == null)
            {
                throw new ArgumentNullException("functionMetadata");
            }
            if (triggerMetadata == null)
            {
                throw new ArgumentNullException("triggerMetadata");
            }
            if (methodAttributes == null)
            {
                throw new ArgumentNullException("methodAttributes");
            }

            var csharpInvoker = functionInvoker as CSharpFunctionInvoker;

            if (csharpInvoker == null)
            {
                throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Expected invoker of type '{0}' but received '{1}'", typeof(CSharpFunctionInvoker).Name, functionInvoker.GetType().Name));
            }

            try
            {
                ApplyMethodLevelAttributes(functionMetadata, triggerMetadata, methodAttributes);

                MethodInfo      functionTarget = csharpInvoker.GetFunctionTargetAsync().Result;
                ParameterInfo[] parameters     = functionTarget.GetParameters();
                Collection <ParameterDescriptor> descriptors = new Collection <ParameterDescriptor>();
                IEnumerable <FunctionBinding>    bindings    = inputBindings.Union(outputBindings);
                bool addHttpRequestSystemParameter           = false;
                foreach (var parameter in parameters)
                {
                    // Is it the trigger parameter?
                    if (string.Compare(parameter.Name, triggerMetadata.Name, StringComparison.Ordinal) == 0)
                    {
                        descriptors.Add(CreateTriggerParameterDescriptor(parameter, triggerMetadata));

                        if (triggerMetadata.Type == BindingType.HttpTrigger &&
                            parameter.ParameterType != typeof(HttpRequestMessage))
                        {
                            addHttpRequestSystemParameter = true;
                        }
                    }
                    else
                    {
                        Type parameterType = parameter.ParameterType;
                        if (parameterType.IsByRef)
                        {
                            parameterType = parameterType.GetElementType();
                        }

                        var descriptor = new ParameterDescriptor(parameter.Name, parameter.ParameterType);
                        var binding    = bindings.FirstOrDefault(b => string.Compare(b.Metadata.Name, parameter.Name, StringComparison.Ordinal) == 0);
                        if (binding != null)
                        {
                            Collection <CustomAttributeBuilder> customAttributes = binding.GetCustomAttributes();
                            if (customAttributes != null)
                            {
                                foreach (var customAttribute in customAttributes)
                                {
                                    descriptor.CustomAttributes.Add(customAttribute);
                                }
                            }
                        }

                        if (parameter.IsOut)
                        {
                            descriptor.Attributes |= ParameterAttributes.Out;
                        }

                        descriptors.Add(descriptor);
                    }
                }

                // Add any additional common System parameters
                // Add ExecutionContext to provide access to InvocationId, etc.
                descriptors.Add(new ParameterDescriptor("context", typeof(ExecutionContext)));

                // If we have an HTTP trigger binding but we're not binding
                // to the HttpRequestMessage, require it as a system parameter
                if (addHttpRequestSystemParameter)
                {
                    descriptors.Add(new ParameterDescriptor(ScriptConstants.DefaultSystemTriggerParameterName, typeof(HttpRequestMessage)));
                }

                return(descriptors);
            }
            catch (AggregateException exc)
            {
                if (!(exc.InnerException is CompilationErrorException))
                {
                    throw;
                }
            }
            catch (CompilationErrorException)
            {
            }

            // We were unable to compile the function to get its signature,
            // setup the descriptor with the default parameters
            return(base.GetFunctionParameters(functionInvoker, functionMetadata, triggerMetadata, methodAttributes, inputBindings, outputBindings));
        }
        protected override async Task <Collection <ParameterDescriptor> > GetFunctionParametersAsync(IFunctionInvoker functionInvoker, FunctionMetadata functionMetadata,
                                                                                                     BindingMetadata triggerMetadata, Collection <CustomAttributeBuilder> methodAttributes, Collection <FunctionBinding> inputBindings, Collection <FunctionBinding> outputBindings)
        {
            if (functionInvoker == null)
            {
                throw new ArgumentNullException(nameof(functionInvoker));
            }
            if (functionMetadata == null)
            {
                throw new ArgumentNullException(nameof(functionMetadata));
            }
            if (triggerMetadata == null)
            {
                throw new ArgumentNullException(nameof(triggerMetadata));
            }
            if (methodAttributes == null)
            {
                throw new ArgumentNullException(nameof(methodAttributes));
            }

            var dotNetInvoker = functionInvoker as DotNetFunctionInvoker;

            if (dotNetInvoker == null)
            {
                throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Expected invoker of type '{0}' but received '{1}'", typeof(DotNetFunctionInvoker).Name, functionInvoker.GetType().Name));
            }

            try
            {
                ApplyMethodLevelAttributes(functionMetadata, triggerMetadata, methodAttributes);

                MethodInfo functionTarget = await dotNetInvoker.GetFunctionTargetAsync();

                ParameterInfo[] parameters = functionTarget.GetParameters();
                Collection <ParameterDescriptor> descriptors = new Collection <ParameterDescriptor>();
                IEnumerable <FunctionBinding>    bindings    = inputBindings.Union(outputBindings);
                ParameterDescriptor descriptor = null;
                foreach (var parameter in parameters)
                {
                    // Is it the trigger parameter?
                    if (string.Compare(parameter.Name, triggerMetadata.Name, StringComparison.Ordinal) == 0)
                    {
                        ParameterDescriptor triggerParameter = CreateTriggerParameter(triggerMetadata, parameter.ParameterType);
                        descriptors.Add(triggerParameter);
                    }
                    else
                    {
                        Type parameterType    = parameter.ParameterType;
                        bool parameterIsByRef = parameterType.IsByRef;
                        if (parameterIsByRef)
                        {
                            parameterType = parameterType.GetElementType();
                        }

                        descriptor = new ParameterDescriptor(parameter.Name, parameter.ParameterType);
                        var binding = bindings.FirstOrDefault(b => string.Compare(b.Metadata.Name, parameter.Name, StringComparison.Ordinal) == 0);
                        if (binding != null)
                        {
                            Collection <CustomAttributeBuilder> customAttributes = binding.GetCustomAttributes(parameter.ParameterType);
                            if (customAttributes != null)
                            {
                                foreach (var customAttribute in customAttributes)
                                {
                                    descriptor.CustomAttributes.Add(customAttribute);
                                }
                            }
                        }

                        if (parameter.IsOut)
                        {
                            descriptor.Attributes |= ParameterAttributes.Out;
                        }

                        descriptors.Add(descriptor);
                    }
                }

                // Add any additional required System parameters (if they haven't already been defined by the user)
                if (!descriptors.Any(p => p.Type == typeof(ExecutionContext)))
                {
                    // Add ExecutionContext to provide access to InvocationId, etc.
                    descriptors.Add(new ParameterDescriptor(ScriptConstants.SystemExecutionContextParameterName, typeof(ExecutionContext)));
                }

                if (TryCreateReturnValueParameterDescriptor(functionTarget.ReturnType, bindings, out descriptor))
                {
                    // If a return value binding has been specified, set up an output
                    // binding to map it to. By convention, this is set up as the last
                    // parameter.
                    descriptors.Add(descriptor);
                }

                return(descriptors);
            }
            catch (AggregateException exc)
            {
                if (!(exc.InnerException is CompilationErrorException))
                {
                    throw;
                }
            }
            catch (CompilationErrorException)
            {
            }

            // We were unable to compile the function to get its signature,
            // setup the descriptor with the default parameters
            methodAttributes.Clear();
            return(await base.GetFunctionParametersAsync(functionInvoker, functionMetadata, triggerMetadata, methodAttributes, inputBindings, outputBindings));
        }
        protected override Collection<ParameterDescriptor> GetFunctionParameters(IFunctionInvoker functionInvoker, FunctionMetadata functionMetadata,
            BindingMetadata triggerMetadata, Collection<CustomAttributeBuilder> methodAttributes, Collection<FunctionBinding> inputBindings, Collection<FunctionBinding> outputBindings)
        {
            if (functionInvoker == null)
            {
                throw new ArgumentNullException("functionInvoker");
            }
            if (functionMetadata == null)
            {
                throw new ArgumentNullException("functionMetadata");
            }
            if (triggerMetadata == null)
            {
                throw new ArgumentNullException("triggerMetadata");
            }
            if (methodAttributes == null)
            {
                throw new ArgumentNullException("methodAttributes");
            }

            var dotNetInvoker = functionInvoker as DotNetFunctionInvoker;
            if (dotNetInvoker == null)
            {
                throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Expected invoker of type '{0}' but received '{1}'", typeof(DotNetFunctionInvoker).Name, functionInvoker.GetType().Name));
            }

            try
            {
                ApplyMethodLevelAttributes(functionMetadata, triggerMetadata, methodAttributes);

                MethodInfo functionTarget = dotNetInvoker.GetFunctionTargetAsync().Result;
                ParameterInfo[] parameters = functionTarget.GetParameters();
                Collection<ParameterDescriptor> descriptors = new Collection<ParameterDescriptor>();
                IEnumerable<FunctionBinding> bindings = inputBindings.Union(outputBindings);
                ParameterDescriptor descriptor = null;
                foreach (var parameter in parameters)
                {
                    // Is it the trigger parameter?
                    if (string.Compare(parameter.Name, triggerMetadata.Name, StringComparison.Ordinal) == 0)
                    {
                        ParameterDescriptor triggerParameter = CreateTriggerParameter(triggerMetadata, parameter.ParameterType);
                        descriptors.Add(triggerParameter);
                    }
                    else
                    {
                        Type parameterType = parameter.ParameterType;
                        bool parameterIsByRef = parameterType.IsByRef;
                        if (parameterIsByRef)
                        {
                            parameterType = parameterType.GetElementType();
                        }

                        descriptor = new ParameterDescriptor(parameter.Name, parameter.ParameterType);
                        var binding = bindings.FirstOrDefault(b => string.Compare(b.Metadata.Name, parameter.Name, StringComparison.Ordinal) == 0);
                        if (binding != null)
                        {
                            Collection<CustomAttributeBuilder> customAttributes = binding.GetCustomAttributes(parameter.ParameterType);
                            if (customAttributes != null)
                            {
                                foreach (var customAttribute in customAttributes)
                                {
                                    descriptor.CustomAttributes.Add(customAttribute);
                                }
                            }
                        }

                        // In the C# programming model, IsOut is set for out parameters
                        // In the F# programming model, neither IsOut nor IsIn are set for byref parameters (which are used as out parameters).
                        //   Justification for this cariation of the programming model is that declaring 'out' parameters is (deliberately)
                        //   awkward in F#, they require opening System.Runtime.InteropServices and adding the [<Out>] attribute, and using 
                        //   a byref parameter. In contrast declaring a byref parameter alone (neither labelled In nor Out) is simple enough.
                        if (parameter.IsOut || (functionMetadata.ScriptType == ScriptType.FSharp && parameterIsByRef && !parameter.IsIn))
                        {
                            descriptor.Attributes |= ParameterAttributes.Out;
                        }

                        descriptors.Add(descriptor);
                    }
                }

                // Add any additional required System parameters (if they haven't already been defined by the user)
                if (!descriptors.Any(p => p.Type == typeof(ExecutionContext)))
                {
                    // Add ExecutionContext to provide access to InvocationId, etc.
                    descriptors.Add(new ParameterDescriptor(ScriptConstants.SystemExecutionContextParameterName, typeof(ExecutionContext)));
                }

                // If we have an HTTP trigger binding but no parameter binds to the raw HttpRequestMessage,
                // add it as a system parameter so it is accessible later in the pipeline.
                if (string.Compare(triggerMetadata.Type, "httptrigger", StringComparison.OrdinalIgnoreCase) == 0 &&
                    !descriptors.Any(p => p.Type == typeof(HttpRequestMessage)))
                {
                    descriptors.Add(new ParameterDescriptor(ScriptConstants.SystemTriggerParameterName, typeof(HttpRequestMessage)));
                }

                if (TryCreateReturnValueParameterDescriptor(functionTarget.ReturnType, bindings, out descriptor))
                {
                    // If a return value binding has been specified, set up an output
                    // binding to map it to. By convention, this is set up as the last
                    // parameter.
                    descriptors.Add(descriptor);
                }

                return descriptors;
            }
            catch (AggregateException exc)
            {
                if (!(exc.InnerException is CompilationErrorException))
                {
                    throw;
                }
            }
            catch (CompilationErrorException)
            {
            }

            // We were unable to compile the function to get its signature,
            // setup the descriptor with the default parameters
            methodAttributes.Clear();
            return base.GetFunctionParameters(functionInvoker, functionMetadata, triggerMetadata, methodAttributes, inputBindings, outputBindings);
        }