internal Request BuildRequest(MemberExpression expression) { var member = expression.Member; // Get the RPCAttribute with service and procedure names object[] attributes = member.GetCustomAttributes(typeof(RPCAttribute), false); if (attributes.Length != 1) { throw new ArgumentException("Invalid expression. Property accessed must be backed by a RPC."); } var attribute = (RPCAttribute)attributes [0]; // Construct the encoded arguments var arguments = new List <ByteString> (); // If it's a class property, pass the class instance as an argument if (ExpressionUtils.IsAClassProperty(expression)) { var instance = expression.Expression; var argumentExpr = Expression.Lambda <Func <object> > (Expression.Convert(instance, typeof(object))); var value = argumentExpr.Compile() (); var type = member.DeclaringType; var encodedValue = Encoder.Encode(value, type); arguments.Add(encodedValue); } // Build the request return(BuildRequest(attribute.Service, attribute.Procedure, arguments)); }
internal static ProcedureCall GetCall(MethodCallExpression expression) { var method = expression.Method; // Get the RPCAttribute with service and procedure names object[] attributes = method.GetCustomAttributes(typeof(RPCAttribute), false); if (attributes.Length != 1) { throw new ArgumentException("Invalid expression. Method called must be backed by a RPC."); } var attribute = (RPCAttribute)attributes [0]; // Construct the encoded arguments var arguments = new List <ByteString> (); // Evaluate the instance on which the method is called // Note: ensures, for example, that the service constructor extension method is called // such that custom exception types are registered // Note: in the case of class methods, is used to get the id of the object // with which to make the call var instanceValue = GetInstanceValue(expression.Object); // Include class instance argument for class methods if (ExpressionUtils.IsAClassMethod(expression)) { var instanceType = method.DeclaringType; arguments.Add(Encoder.Encode(instanceValue, instanceType)); } // Include arguments from the expression int position = 0; foreach (var argument in expression.Arguments) { // Skip connection parameter to static class methods if (position == 0 && ExpressionUtils.IsAClassStaticMethod(expression)) { position++; continue; } var argumentExpr = Expression.Lambda <Func <object> > (Expression.Convert(argument, typeof(object))); var value = argumentExpr.Compile() (); var type = method.GetParameters() [position].ParameterType; var encodedValue = Encoder.Encode(value, type); arguments.Add(encodedValue); position++; } return(GetCall(attribute.Service, attribute.Procedure, arguments)); }
internal Request BuildRequest(MethodCallExpression expression) { var method = expression.Method; // Get the RPCAttribute with service and procedure names object[] attributes = method.GetCustomAttributes(typeof(RPCAttribute), false); if (attributes.Length != 1) { throw new ArgumentException("Invalid expression. Method called must be backed by a RPC."); } var attribute = (RPCAttribute)attributes [0]; // Construct the encoded arguments var arguments = new List <ByteString> (); // Include class instance argument for class methods if (ExpressionUtils.IsAClassMethod(expression)) { var instance = expression.Object; var instanceExpr = Expression.Lambda <Func <object> > (Expression.Convert(instance, typeof(object))); var instanceValue = instanceExpr.Compile() (); var instanceType = method.DeclaringType; arguments.Add(Encoder.Encode(instanceValue, instanceType)); } // Include arguments from the expression int position = 0; foreach (var argument in expression.Arguments) { // Skip connection parameter to static class methods if (position == 0 && ExpressionUtils.IsAClassStaticMethod(expression)) { position++; continue; } var argumentExpr = Expression.Lambda <Func <object> > (Expression.Convert(argument, typeof(object))); var value = argumentExpr.Compile() (); var type = method.GetParameters() [position].ParameterType; var encodedValue = Encoder.Encode(value, type); arguments.Add(encodedValue); position++; } // Build the request return(BuildRequest(attribute.Service, attribute.Procedure, arguments)); }