コード例 #1
0
        public override Task <object> InterceptAsync(MethodInfo methodInfo, object[] methodArguments)
        {
            SynchronizeServices();

            var count      = Interlocked.Increment(ref counter);
            var candidates = services;
            var candidate  = candidates[count % candidates.Length];

            IAsyncInterceptor asyncInterceptor;

            if (AsyncInterceptorUtilities.TryGetAsyncInterceptor(candidate, out asyncInterceptor))
            {
                return(asyncInterceptor.InterceptAsync(methodInfo, methodArguments));
            }
            else
            {
                return(Task.FromResult(methodInfo.Invoke(candidate, methodArguments)));
            }
        }
コード例 #2
0
        public async Task <object> EvaluateAsync(Expression expression)
        {
            DebugWriteLine("At expression: " + expression);
            if (expression is ConstantExpression)
            {
                return(((ConstantExpression)expression).Value);
            }
            else if (expression is MethodCallExpression)
            {
                var methodCallExpression      = expression as MethodCallExpression;
                var methodObjectExpression    = methodCallExpression.Object;
                var methodArgumentExpressions = methodCallExpression.Arguments;
                var methodArguments           = new object[methodArgumentExpressions.Count];
                for (var i = 0; i < methodArgumentExpressions.Count; i++)
                {
                    var methodArgumentExpression = methodArgumentExpressions[i];
                    DebugWriteLine($"{i}: {methodArgumentExpression.NodeType}, {methodArgumentExpression.Type}");
                    methodArguments[i] = await EvaluateAsync(methodArgumentExpression);
                }
                object invocationReturnValue = null;
                if (methodObjectExpression == null)
                {
                    var method = methodCallExpression.Method;
                    invocationReturnValue = method.Invoke(null, methodArguments);
                }
                else
                {
                    var methodObject = await EvaluateAsync(methodCallExpression.Object);

                    IAsyncInterceptor asyncInterceptor;
                    if (AsyncInterceptorUtilities.TryGetAsyncInterceptor(methodObject, out asyncInterceptor))
                    {
                        DebugWriteLine($"!> Asynchronously invoking service method {methodCallExpression.Method.Name}!");
                        invocationReturnValue = await asyncInterceptor.InterceptAsync(methodCallExpression.Method, methodArguments);
                    }
                    else
                    {
                        var method = methodCallExpression.Method;
                        invocationReturnValue = method.Invoke(methodObject, methodArguments);
                    }
                }
                var methodParameters = methodCallExpression.Method.GetParameters();
                for (var i = 0; i < methodParameters.Length; i++)
                {
                    var methodParameter = methodParameters[i];
                    if (methodParameter.IsOut || methodParameter.ParameterType.IsByRef)
                    {
                        await SetOutOrRef(methodArgumentExpressions[i], methodArguments[i]);
                    }
                }
                return(invocationReturnValue);
            }
            else if (expression is MemberExpression)
            {
                var memberExpression = (MemberExpression)expression;
                switch (memberExpression.Member.MemberType)
                {
                case MemberTypes.Field:
                    var objectExpression = Expression.Convert(memberExpression, typeof(object));
                    var getterExpression = Expression.Lambda <Func <object> >(objectExpression);
                    var memberValue      = getterExpression.Compile().Invoke();
                    DebugWriteLine("!! member: " + memberValue + " " + memberExpression.NodeType + " " + memberExpression.Member.Name + " " + memberExpression.Member.MemberType);
                    return(memberValue);

                case MemberTypes.Property:
                    var property       = ((PropertyInfo)memberExpression.Member);
                    var getterMethod   = property.GetGetMethod();
                    var thisExpression = await EvaluateAsync(memberExpression.Expression);

                    DebugWriteLine("!! property: " + getterMethod + " " + memberExpression.NodeType + " " + memberExpression.Member.Name + " " + memberExpression.Member.MemberType);
                    return(await EvaluateAsync(Expression.Call(Expression.Constant(thisExpression), getterMethod)));

                default:
                    DebugWriteLine(memberExpression.ToString());
                    Console.WriteLine(memberExpression.NodeType + " " + memberExpression.GetType() + " " + memberExpression.CanReduce);
                    throw new NotImplementedException();
                }
            }
            else if (expression is UnaryExpression)
            {
                var unaryExpression = (UnaryExpression)expression;
                var operand         = await EvaluateAsync(unaryExpression.Operand);

                switch (unaryExpression.NodeType)
                {
                case ExpressionType.Convert:
                    return(Convert.ChangeType(operand, unaryExpression.Type));

                default:
                    DebugWriteLine(unaryExpression.ToString());
                    Console.WriteLine(unaryExpression.NodeType + " " + unaryExpression.GetType() + " " + unaryExpression.CanReduce);
                    throw new NotImplementedException();
                }
            }
            else if (expression is BinaryExpression)
            {
                var binaryExpression = (BinaryExpression)expression;
                var left             = await EvaluateAsync(binaryExpression.Left);

                var right = await EvaluateAsync(binaryExpression.Right);

                switch (binaryExpression.NodeType)
                {
                case ExpressionType.ArrayIndex:
                    var indexingExpression = Expression.ArrayIndex(Expression.Constant(left), Expression.Constant(right));
                    return(GetExpressionResult(indexingExpression));

                case ExpressionType.Add:
                case ExpressionType.Subtract:
                case ExpressionType.Multiply:
                case ExpressionType.Divide:
                    return(GetExpressionResult(Expression.MakeBinary(binaryExpression.NodeType, Expression.Constant(left), Expression.Constant(right))));

                default:
                    DebugWriteLine(binaryExpression.ToString());
                    Console.WriteLine(binaryExpression.NodeType + " " + binaryExpression.GetType() + " " + binaryExpression.CanReduce);
                    throw new NotImplementedException();
                }
            }
            else
            {
                Console.WriteLine(expression.NodeType + " " + expression.GetType() + " " + expression.CanReduce);
                throw new NotImplementedException();
            }
        }