void IInterceptor.Intercept(IInvocation invocation)
        {
            try
            {
                // Get the AsyncServiceMethodInfo of the method to call.
                AsyncServiceMethodInfo asyncServiceMethodInfo = AsyncServiceMethodInfos.GetOrAdd(
                    invocation.Method,
                    AsyncServiceMethodInfoFactory.CreateFromMethodInfo);

                // Get the (optional) parameter for the method call.
                //object requestObject = invocation.Arguments.Length == 0 ? null : invocation.Arguments[0];

                ParameterInfo[] parameters = invocation.Method.GetParameters();
                if (parameters.Length != invocation.Arguments.Length)
                {
                    throw new InvalidOperationException("Hm. The number of method parameters doesn't match the number of arguments...");
                }

                CallParam[] callParams = parameters
                                         .Zip(invocation.Arguments, (param, arg) => new CallParam(param.Name, param.ParameterType, arg))
                                         .ToArray();

                // Call the service (as a task, i.e. the work is not performed right here but at the next await or GetResult statement).
                Task <object> taskOfObject = _serverCaller.Call(asyncServiceMethodInfo, callParams);

                // Get a convert method from Task<object> to Task<T> where T is the actual return type of this particular method.
                MethodInfo specificConvertMethod = SpecificConvertTaskMethods.GetOrAdd(
                    asyncServiceMethodInfo.ReturnType,
                    GenericConvertTaskMethod.MakeGenericMethod(asyncServiceMethodInfo.ReturnType));

                // Convert the Task<object> to Task<T>.
                object taskOfT = specificConvertMethod.Invoke(null, new object[] { taskOfObject });

                // Assign the resulting Task<T> as the return value.
                invocation.ReturnValue = taskOfT;
            }
            catch (Exception exception)
            {
                // Crikey!
                Debug.WriteLine($"Exception in {nameof(ServiceInterceptor)} calling {invocation.Method.Name} on the service {invocation.Method.DeclaringType}: \r\n{exception}");
                Debugger.Break();
                throw;
            }
        }
示例#2
0
        public async Task <object> Call(AsyncServiceMethodInfo asyncServiceMethodInfo, CallParam[] callParams)
        {
            try
            {
                // Get the URI for the HTTP server call.
                ServerPath path = ServerPaths.GetServerPath(asyncServiceMethodInfo);

                using (var httpClient = new HttpClient())
                {
                    using (HttpContent content = HttpContentSupport.Create(callParams))
                    {
                        HttpResponseMessage response = await httpClient.PostAsync(_rootUri + path, content).ConfigureAwait(false);

                        if (!response.IsSuccessStatusCode)
                        {
                            throw new ServerCallException(asyncServiceMethodInfo, response.StatusCode);
                        }

                        using (Stream responseStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false))
                        {
                            if (responseStream == null)
                            {
                                throw new ServerCallException(asyncServiceMethodInfo, HttpStatusCode.NoContent);
                            }

                            using (var reader = new StreamReader(responseStream, Encoding.UTF8))
                            {
                                string responseJson = await reader.ReadToEndAsync().ConfigureAwait(false);

                                return(JsonConvert.DeserializeObject(responseJson, asyncServiceMethodInfo.ReturnType));
                            }
                        }
                    }
                }
            }
            catch (Exception exception)
            {
                throw new ServerCallException(asyncServiceMethodInfo, "Exception during server method call", exception);
            }
        }
 public ServiceMethod(object instance, MethodInfo methodInfo, AsyncServiceMethodInfo asyncServiceMethodInfo)
 {
     Instance               = instance;
     MethodInfo             = methodInfo;
     AsyncServiceMethodInfo = asyncServiceMethodInfo;
 }
示例#4
0
 public ServerCallException(AsyncServiceMethodInfo serviceMethodInfo, HttpStatusCode statusCode)
 {
     ServiceMethodInfo = serviceMethodInfo;
     StatusCode        = statusCode;
 }
示例#5
0
 public ServerCallException(AsyncServiceMethodInfo serviceMethodInfo, string message, Exception innerException)
     : base(message, innerException)
 {
     ServiceMethodInfo = serviceMethodInfo;
 }