Example #1
0
        private static LambdaExpression ReplaceEnumerables(IConnectQlFunctions functions, string name, LambdaExpression lambda)
        {
            while (lambda.Parameters.Any(p => p.Type.HasInterface(typeof(IEnumerable <>)) && p.Type != typeof(string)))
            {
                var replacements = lambda.Parameters
                                   .Select(p => new
                {
                    Original  = p,
                    ReplaceBy = p.Type.HasInterface(typeof(IEnumerable <>)) && p.Type != typeof(string) ?
                                Expression.Parameter(typeof(IAsyncEnumerable <>).MakeGenericType(p.Type.GenericTypeArguments[0]), p.Name) :
                                p,
                })
                                   .ToArray();

                var enumerableParameter = replacements.First(p => p.ReplaceBy.Type.HasInterface(typeof(IAsyncEnumerable <>)));

                functions.Logger?.Warning($"Parameter {enumerableParameter.Original.Name} of function {name} is an IEnumerable<T>, this reduces performance, consider using IAsyncEnumerable<T>.");

                lambda = Expression.Lambda(
                    GenericVisitor.Visit(
                        (MethodCallExpression e) =>
                        e.Object != enumerableParameter.Original && !e.Arguments.Contains(enumerableParameter.Original)
                                ? null
                                : TaskExpression.Task(
                            Expression.Call(
                                ConnectQlFunctionsExtensions.ApplyEnumerableFunction.MakeGenericMethod(enumerableParameter.Original.Type.GenericTypeArguments[0], e.Type),
                                enumerableParameter.ReplaceBy,
                                Expression.Lambda(e, enumerableParameter.Original))),
                        lambda.Body),
                    replacements.Select(r => r.ReplaceBy));
            }

            return(lambda);
        }
Example #2
0
        public static IFunctionRegistration AddWithoutSideEffects <TResult>([NotNull] this IConnectQlFunctions functions, string key, Expression <Func <TResult> > function)
        {
            var descriptor = new FunctionDescriptor(key, false, ConnectQlFunctionsExtensions.ReplaceEnumerables(functions, key, function));

            return(new FunctionRegistration(descriptor, functions.AddFunction(key, descriptor)));
        }
Example #3
0
        public static IFunctionRegistration6 AddWithSideEffects <TArgument1, TArgument2, TArgument3, TArgument4, TArgument5, TArgument6, TResult>([NotNull] this IConnectQlFunctions functions, string key, Expression <Func <TArgument1, TArgument2, TArgument3, TArgument4, TArgument5, TArgument6, TResult> > function)
        {
            var descriptor = new FunctionDescriptor(key, true, ConnectQlFunctionsExtensions.ReplaceEnumerables(functions, key, function));

            return(new FunctionRegistration(descriptor, functions.AddFunction(key, descriptor)));
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="FunctionRegistration"/> class.
 /// </summary>
 /// <param name="descriptor">
 /// The descriptor.
 /// </param>
 /// <param name="functions">
 /// The functions.
 /// </param>
 internal FunctionRegistration(FunctionDescriptor descriptor, IConnectQlFunctions functions)
 {
     this.descriptor = descriptor;
     this.functions  = functions;
 }