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; } }
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; }
public ServerCallException(AsyncServiceMethodInfo serviceMethodInfo, HttpStatusCode statusCode) { ServiceMethodInfo = serviceMethodInfo; StatusCode = statusCode; }
public ServerCallException(AsyncServiceMethodInfo serviceMethodInfo, string message, Exception innerException) : base(message, innerException) { ServiceMethodInfo = serviceMethodInfo; }