public async Task <object> Call(IHttpHandler httpHandler, string baseUrl, HttpApiArguments arguments, HttpApiInstrumenter apiInstrumenter = null) { async void ApplyArguments(Func <IHttpArgumentHandler, string, object, Task> applier) { foreach (var item in ArgumentHandlers) { var name = item.Key; if (arguments.TryGetValue(name, out var argument)) { var handler = item.Value; await applier(handler, name, argument); } } } HttpApiRequest GetRequest() { var request = new HttpApiRequest { Url = Url.CreateUrl(baseUrl), Method = HttpMethod, Headers = Headers.ToList() }; ApplyArguments(async(handler, name, argument) => await handler.ApplyArgument(request, name, argument)); if (!request.Headers.Exists(x => x.Name == "Content-Type") && request.Body != null) { var contentType = request.Body.Accept(new ContentTypeCalculator()); request.Headers.Add(new HttpHeader("Content-Type", contentType)); } return(request); } async Task <HttpHandlerResponse> GetResponse(HttpApiRequest request) { return(await httpHandler.Call(request)); } async Task <object> GetResult(HttpApiRequest request, HttpHandlerResponse response) { ApplyArguments(async(handler, name, argument) => await handler.ApplyArgument(response.ApiResponse, name, argument)); return(await ResponseHandler.HandleResponse(request, response.ApiResponse)); } IHttpApiInstrumentation instrumentation = new DefaultHttpApiInstrumentation(GetRequest, GetResponse, GetResult); if (apiInstrumenter != null) { instrumentation = apiInstrumenter(this, arguments, instrumentation); } return(await MakeCall(instrumentation)); }
public Task <object> Call(Invocation invocation) { if (!api.Endpoints.TryGetValue(invocation.Method, out var endpoint)) { throw new Exception($"Endpoint not found for: \"{invocation.Method.DeclaringType.FullName}.{invocation.Method.Name}\". Perhaps you forgot to decorate your method with [Get], [Post], etc."); } var arguments = new HttpApiArguments(invocation.Method .GetParameters() .Select((x, i) => new { x.Name, Value = invocation.Arguments[i] }) .ToDictionary(x => x.Name, x => x.Value)); if (proxy is Api) { return(((Api)(object)proxy).Call(endpoint, httpHandler, baseUrl, arguments, apiInstrumenter)); } else { var call = endpoint.Call(httpHandler, baseUrl, arguments, apiInstrumenter); return(call); } }