/// <summary> /// Initializes a new <see cref="ALambdaTopicFunction{TMessage}"/> instance using a /// custom implementation of <see cref="ILambdaFunctionDependencyProvider"/>. /// </summary> /// <param name="serializer">Custom implementation of <see cref="ILambdaJsonSerializer"/>.</param> /// <param name="provider">Custom implementation of <see cref="ILambdaFunctionDependencyProvider"/>.</param> protected ALambdaTopicFunction(ILambdaJsonSerializer serializer, ILambdaFunctionDependencyProvider?provider) : base(provider) { LambdaSerializer = serializer ?? throw new ArgumentNullException(nameof(serializer)); }
//--- Constructors --- /// <summary> /// Initializes a new <see cref="ALambdaTopicFunction{TMessage}"/> instance using the default /// implementation of <see cref="ILambdaFunctionDependencyProvider"/>. /// </summary> /// <param name="serializer">Custom implementation of <see cref="ILambdaJsonSerializer"/>.</param> protected ALambdaTopicFunction(ILambdaJsonSerializer serializer) : this(serializer, provider : null) { }
//--- Constructors --- /// <summary> /// Initializes a new <see cref="ALambdaApiGatewayFunction"/> instance using the default implementation of <see cref="ILambdaFunctionDependencyProvider"/>. /// </summary> /// <param name="serializer">Custom implementation of <see cref="ILambdaJsonSerializer"/>.</param> protected ALambdaApiGatewayFunction(ILambdaJsonSerializer serializer) : this(serializer, provider : null) { }
/// <summary> /// Initializes a new <see cref="ALambdaQueueFunction{TMessage}"/> instance using a /// custom implementation of <see cref="ILambdaQueueFunctionDependencyProvider"/>. /// </summary> /// <param name="serializer">Custom implementation of <see cref="ILambdaJsonSerializer"/>.</param> /// <param name="provider">Custom implementation of <see cref="ILambdaQueueFunctionDependencyProvider"/>.</param> protected ALambdaQueueFunction(ILambdaJsonSerializer serializer, ILambdaQueueFunctionDependencyProvider?provider) : base(provider ?? new LambdaQueueFunctionDependencyProvider()) { LambdaSerializer = serializer ?? throw new System.ArgumentNullException(nameof(serializer)); }
//--- Constructors --- /// <summary> /// Initializes a new <see cref="ALambdaCustomResourceFunction{TProperties,TAttributes}"/> instance using the default /// implementation of <see cref="ILambdaFunctionDependencyProvider"/>. /// </summary> /// <param name="serializer">Custom implementation of <see cref="ILambdaJsonSerializer"/>.</param> protected ALambdaCustomResourceFunction(ILambdaJsonSerializer serializer) : this(serializer, provider : null) { }
private static Func <APIGatewayProxyRequest, InvocationTargetState, object?> CreateParameterResolver(ILambdaJsonSerializer serializer, MethodInfo method, ParameterInfo parameter) { // check if [FromUri] or [FromBody] attributes are present var hasFromUriAttribute = parameter.GetCustomAttribute <FromUriAttribute>() != null; var hasFromBodyAttribute = parameter.GetCustomAttribute <FromBodyAttribute>() != null; if (hasFromUriAttribute && hasFromBodyAttribute) { throw new ApiGatewayInvocationTargetParameterException(method, parameter, "cannot have both [FromUri] and [FromBody] attributes"); } // check if parameter is a proxy request var isProxyRequest = parameter.ParameterType == typeof(APIGatewayProxyRequest); if (isProxyRequest) { // parameter is the proxy request itself return((request, state) => request); } // check if parameter needs to deserialized from URI or BODY var isSimpleType = parameter.ParameterType.IsValueType || (parameter.ParameterType == typeof(string)); if ((isSimpleType && !hasFromBodyAttribute) || hasFromUriAttribute) { // check if parameter is read from URI string directly or if its members are read from the URI string if (isSimpleType) { // create function for getting default parameter value Func <object?> getDefaultValue; if (parameter.IsOptional) { getDefaultValue = () => parameter.DefaultValue; } else if ((Nullable.GetUnderlyingType(parameter.ParameterType) == null) && (parameter.ParameterType.IsValueType || parameter.ParameterType == typeof(string))) { getDefaultValue = () => throw new ApiGatewayInvocationTargetParameterException(method, parameter, "missing value"); } else { getDefaultValue = () => null; } // create function to resolve parameter return((request, state) => { string?value = null; // attempt to resolve the parameter from stage variables, path parameters, and query string parameters var success = (request.PathParameters?.TryGetValue(parameter.Name, out value) ?? false) || (request.QueryStringParameters?.TryGetValue(parameter.Name, out value) ?? false); // if resolved, return the converted value; otherwise the default value if (success) { try { return Convert.ChangeType(value, parameter.ParameterType); } catch (FormatException) { throw new ApiGatewayInvocationTargetParameterException(method, parameter, "invalid parameter format"); } } return getDefaultValue(); }); } else { var queryParameterType = parameter.ParameterType; // parameter represents the query-string key-value pairs return((request, state) => { try { // construct a unified JSON representation of the path and query-string parameters if (state.PathQueryParametersJson == null) { var pathParameters = request.PathParameters ?? Enumerable.Empty <KeyValuePair <string, string> >(); var queryStringParameters = request.QueryStringParameters ?? Enumerable.Empty <KeyValuePair <string, string> >(); state.PathQueryParametersJson = serializer.Serialize( pathParameters.Union(queryStringParameters) .GroupBy(kv => kv.Key) .Select(grouping => grouping.First()) .ToDictionary(kv => kv.Key, kv => kv.Value) ); } return serializer.Deserialize(state.PathQueryParametersJson, parameter.ParameterType); } catch { throw new ApiGatewayInvocationTargetParameterException(method, parameter, "invalid path/query-string parameters format"); } }); } } else { // parameter represents the body of the request return((request, state) => { try { return serializer.Deserialize(request.Body, parameter.ParameterType); } catch { throw new ApiGatewayInvocationTargetParameterException(method, parameter, "invalid JSON document in request body"); } }); } }