├── .gitattributes ├── .gitignore ├── GitVersion.yml ├── LICENSE ├── README.md ├── build ├── build.cake ├── build.ps1 ├── build.sh ├── cake.config └── tools │ └── packages.config ├── docs └── images │ ├── benchmark_nura.png │ └── benchmark_s8.png └── src ├── RestLess.Benchmarks.Core ├── Benchmark.cs ├── BenchmarkHttpMessageHandler.cs ├── BenchmarkResult.cs ├── Benchmarker.cs ├── Interfaces │ ├── IRefitApi.cs │ ├── IRefitApi01.cs │ ├── IRestLessApi.cs │ └── IRestLessApi01.cs ├── PerformanceTesters │ ├── PerformanceTester.cs │ ├── RefitPerformanceTester.cs │ └── RestLessPerformanceTester.cs └── RestLess.Benchmarks.Core.csproj ├── RestLess.Benchmarks.Droid ├── Assets │ └── AboutAssets.txt ├── GettingStarted.Xamarin ├── MainActivity.cs ├── Properties │ ├── AndroidManifest.xml │ └── AssemblyInfo.cs ├── Resources │ ├── AboutResources.txt │ ├── Resource.Designer.cs │ ├── layout │ │ ├── ChartCardView.axml │ │ └── Main.axml │ └── values │ │ └── Strings.xml ├── RestLess.Benchmarks.Droid.csproj ├── app.config └── packages.config ├── RestLess.Benchmarks ├── Program.cs └── RestLess.Benchmarks.csproj ├── RestLess.ConsoleSample ├── DelegatingLoggingHandler.cs ├── GitHub │ └── V3 │ │ ├── Entities │ │ ├── SearchResult.cs │ │ └── User.cs │ │ └── IGitHubApi.cs ├── Program.cs └── RestLess.ConsoleSample.csproj ├── RestLess.Core.Tests ├── Helpers │ ├── DefaultFormFormatterTests.cs │ └── UriTemplateHelperTests.cs ├── RestLess.Core.Tests.csproj ├── RestRequest │ └── RestRequestTests.cs └── SimpleRestClient.cs ├── RestLess.Core ├── Exceptions │ └── RestClientException.cs ├── Extensions │ ├── HttpHeadersExtensions.cs │ └── StringBuilderExtensions.cs ├── Helpers │ ├── DefaultMediaFormatter.cs │ ├── DefaultValueFormatter.cs │ └── UriTemplateHelper.cs ├── Http │ └── ObjectContent.cs ├── Interfaces │ └── IHeaderWriter.cs ├── Properties │ └── Assembly.cs ├── RestLess.Core.csproj ├── RestRequest.cs ├── RestRequest │ ├── RestRequest.Content.cs │ ├── RestRequest.Ctor.cs │ ├── RestRequest.Formatters.cs │ ├── RestRequest.Headers.cs │ ├── RestRequest.NestedClasses.cs │ ├── RestRequest.Send.cs │ ├── RestRequest.Url.cs │ └── RestRequest.Validation.cs ├── RestSettingStore.cs └── RestSettings.cs ├── RestLess.Newtonsoft.Json ├── JsonFormFormatter.cs ├── JsonMediaTypeFormatter.cs ├── JsonRestSettings.cs ├── Properties │ └── Assembly.cs └── RestLess.Newtonsoft.Json.csproj ├── RestLess.Sample ├── Constants.cs ├── IRestApi01.cs ├── RestLess.Sample.csproj └── Test.cs ├── RestLess.Shared ├── Attributes │ ├── ContentAttribute.cs │ ├── FormUrlEncodedContentAttribute.cs │ ├── Formatters │ │ ├── FormFormatterAttribute.cs │ │ ├── MediaTypeFormatterAttribute.cs │ │ └── UrlParameterFormatterAttribute.cs │ ├── HeaderAttribute.cs │ ├── HeaderValueAttribute.cs │ ├── HttpMethods │ │ ├── DeleteAttribute.cs │ │ ├── GetAttribute.cs │ │ ├── HeadAttribute.cs │ │ ├── OptionsAttribute.cs │ │ ├── PatchAttribute.cs │ │ ├── PostAttribute.cs │ │ ├── PutAttribute.cs │ │ └── TraceAttribute.cs │ ├── NameAttribute.cs │ ├── NameIgnoreAttribute.cs │ ├── UriTemplatePrefixAttribute.cs │ └── UriTemplateSuffixAttribute.cs ├── Extensions │ ├── IEnumerableExtensions.cs │ └── StringExtensions.cs ├── Helpers │ ├── Check.cs │ └── DefaultFormFormatter.cs ├── Interfaces │ ├── IFormFormatter.cs │ ├── IMediaTypeFormatter.cs │ ├── IRestClient.cs │ └── IRestRequest.cs ├── RestClientBase.cs ├── RestClientFactory.cs ├── RestLess.Shared.projitems ├── RestLess.Shared.shproj ├── RestRequest.cs └── RestSettings.Shared.cs ├── RestLess.Tasks.Tests ├── Constants.cs ├── Generation │ ├── RequestInfoTests.cs │ └── RestClientGeneratorTests.cs ├── RestInterfaces │ ├── IRestApi00.cs │ ├── IRestApi01.cs │ ├── IRestApi02.cs │ ├── IRestApi03.cs │ └── IRestApi04.cs └── RestLess.Tasks.Tests.csproj ├── RestLess.Tasks ├── BuildRestClientsTask.cs ├── Diagnostics │ ├── Codes.cs │ ├── Diagnostic.cs │ ├── ErrorDiagnostic.cs │ ├── Errors │ │ ├── InterfaceError.cs │ │ ├── MethodError.cs │ │ ├── MissingHttpAttributeError.cs │ │ ├── MultipleHttpAttributesError.cs │ │ ├── MultipleRestAttributesError.cs │ │ ├── ParameterError.cs │ │ └── ReturnTypeError.cs │ └── WarningDiagnostic.cs ├── Entities │ ├── ContentArgument.cs │ ├── FormUlrEncodedContentArgument.cs │ ├── RequestAttribute.cs │ └── RequestAttributeType.cs ├── Exceptions │ └── ErrorDiagnosticException.cs ├── Extensions │ ├── IEnumerableExtensions.cs │ ├── RoslynExtensions.Attributes.cs │ └── RoslynExtensions.cs ├── Generation │ ├── CodeBuilder.cs │ ├── RequestInfo.cs │ ├── RestClientBuilder.cs │ ├── RestClientFactoryBuilder.cs │ └── RestClientInfo.cs ├── Helpers │ ├── Constants.cs │ ├── SyntaxNormalizer.cs │ ├── UsingDirectiveSyntaxComparer.cs │ └── UsingDirectiveSyntaxEqualityComparer.cs ├── Properties │ └── Assembly.cs ├── RestClient.cs └── RestLess.Tasks.csproj ├── RestLess.Tests ├── Assets │ └── Api07File.xml ├── Entities │ ├── PagedResponse.cs │ ├── Person.cs │ └── SubNamespaceObject.cs ├── Interfaces │ ├── IApi01.cs │ ├── IApi02.cs │ ├── IApi03.cs │ ├── IApi04.cs │ ├── IApi05.cs │ ├── IApi06.cs │ ├── IApi07.cs │ ├── IApi08.cs │ ├── IApi09.cs │ └── IApi10.cs ├── RestLess.Tests.csproj └── Tests │ ├── Api01Tests.cs │ ├── Api02Tests.cs │ ├── Api03Tests.cs │ ├── Api04Tests.cs │ ├── Api05Tests.cs │ ├── Api06Tests.cs │ ├── Api07Tests.cs │ ├── Api08Tests.cs │ └── Api09Tests.cs ├── RestLess.sln └── RestLess ├── RestLess.csproj ├── build ├── RestLess.props └── RestLess.targets └── buildMultiTargeting └── RestLess.targets /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /GitVersion.yml: -------------------------------------------------------------------------------- 1 | mode: ContinuousDelivery 2 | branches: {} 3 | ignore: 4 | sha: [] 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 letsar 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /build/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ########################################################################## 4 | # This is the Cake bootstrapper script for Linux and OS X. 5 | # This file was downloaded from https://github.com/cake-build/resources 6 | # Feel free to change this file to fit your needs. 7 | ########################################################################## 8 | 9 | # Define directories. 10 | SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) 11 | TOOLS_DIR=$SCRIPT_DIR/tools 12 | ADDINS_DIR=$TOOLS_DIR/Addins 13 | MODULES_DIR=$TOOLS_DIR/Modules 14 | NUGET_EXE=$TOOLS_DIR/nuget.exe 15 | CAKE_EXE=$TOOLS_DIR/Cake/Cake.exe 16 | PACKAGES_CONFIG=$TOOLS_DIR/packages.config 17 | PACKAGES_CONFIG_MD5=$TOOLS_DIR/packages.config.md5sum 18 | ADDINS_PACKAGES_CONFIG=$ADDINS_DIR/packages.config 19 | MODULES_PACKAGES_CONFIG=$MODULES_DIR/packages.config 20 | 21 | # Define md5sum or md5 depending on Linux/OSX 22 | MD5_EXE= 23 | if [[ "$(uname -s)" == "Darwin" ]]; then 24 | MD5_EXE="md5 -r" 25 | else 26 | MD5_EXE="md5sum" 27 | fi 28 | 29 | # Define default arguments. 30 | SCRIPT="build.cake" 31 | CAKE_ARGUMENTS=() 32 | 33 | # Parse arguments. 34 | for i in "$@"; do 35 | case $1 in 36 | -s|--script) SCRIPT="$2"; shift ;; 37 | --) shift; CAKE_ARGUMENTS+=("$@"); break ;; 38 | *) CAKE_ARGUMENTS+=("$1") ;; 39 | esac 40 | shift 41 | done 42 | 43 | # Make sure the tools folder exist. 44 | if [ ! -d "$TOOLS_DIR" ]; then 45 | mkdir "$TOOLS_DIR" 46 | fi 47 | 48 | # Make sure that packages.config exist. 49 | if [ ! -f "$TOOLS_DIR/packages.config" ]; then 50 | echo "Downloading packages.config..." 51 | curl -Lsfo "$TOOLS_DIR/packages.config" https://cakebuild.net/download/bootstrapper/packages 52 | if [ $? -ne 0 ]; then 53 | echo "An error occured while downloading packages.config." 54 | exit 1 55 | fi 56 | fi 57 | 58 | # Download NuGet if it does not exist. 59 | if [ ! -f "$NUGET_EXE" ]; then 60 | echo "Downloading NuGet..." 61 | curl -Lsfo "$NUGET_EXE" https://dist.nuget.org/win-x86-commandline/latest/nuget.exe 62 | if [ $? -ne 0 ]; then 63 | echo "An error occured while downloading nuget.exe." 64 | exit 1 65 | fi 66 | fi 67 | 68 | # Restore tools from NuGet. 69 | pushd "$TOOLS_DIR" >/dev/null 70 | if [ ! -f "$PACKAGES_CONFIG_MD5" ] || [ "$( cat "$PACKAGES_CONFIG_MD5" | sed 's/\r$//' )" != "$( $MD5_EXE "$PACKAGES_CONFIG" | awk '{ print $1 }' )" ]; then 71 | find . -type d ! -name . | xargs rm -rf 72 | fi 73 | 74 | mono "$NUGET_EXE" install -ExcludeVersion 75 | if [ $? -ne 0 ]; then 76 | echo "Could not restore NuGet tools." 77 | exit 1 78 | fi 79 | 80 | $MD5_EXE "$PACKAGES_CONFIG" | awk '{ print $1 }' >| "$PACKAGES_CONFIG_MD5" 81 | 82 | popd >/dev/null 83 | 84 | # Restore addins from NuGet. 85 | if [ -f "$ADDINS_PACKAGES_CONFIG" ]; then 86 | pushd "$ADDINS_DIR" >/dev/null 87 | 88 | mono "$NUGET_EXE" install -ExcludeVersion 89 | if [ $? -ne 0 ]; then 90 | echo "Could not restore NuGet addins." 91 | exit 1 92 | fi 93 | 94 | popd >/dev/null 95 | fi 96 | 97 | # Restore modules from NuGet. 98 | if [ -f "$MODULES_PACKAGES_CONFIG" ]; then 99 | pushd "$MODULES_DIR" >/dev/null 100 | 101 | mono "$NUGET_EXE" install -ExcludeVersion 102 | if [ $? -ne 0 ]; then 103 | echo "Could not restore NuGet modules." 104 | exit 1 105 | fi 106 | 107 | popd >/dev/null 108 | fi 109 | 110 | # Make sure that Cake has been installed. 111 | if [ ! -f "$CAKE_EXE" ]; then 112 | echo "Could not find Cake.exe at '$CAKE_EXE'." 113 | exit 1 114 | fi 115 | 116 | # Start Cake 117 | exec mono "$CAKE_EXE" $SCRIPT "${CAKE_ARGUMENTS[@]}" 118 | -------------------------------------------------------------------------------- /build/cake.config: -------------------------------------------------------------------------------- 1 | ; This is the default configuration file for Cake. 2 | ; This file was downloaded from https://github.com/cake-build/resources 3 | 4 | [Nuget] 5 | Source=https://packages.nuget.org/api/v2 6 | 7 | [Roslyn] 8 | NuGetSource=https://packages.nuget.org/api/v2 9 | 10 | [Paths] 11 | Tools=./tools 12 | Addins=./tools/Addins 13 | Modules=./tools/Modules 14 | -------------------------------------------------------------------------------- /build/tools/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /docs/images/benchmark_nura.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/letsar/RestLess/e370d34c0afa93b1b72a1200ed36c54c5ecc152f/docs/images/benchmark_nura.png -------------------------------------------------------------------------------- /docs/images/benchmark_s8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/letsar/RestLess/e370d34c0afa93b1b72a1200ed36c54c5ecc152f/docs/images/benchmark_s8.png -------------------------------------------------------------------------------- /src/RestLess.Benchmarks.Core/Benchmark.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.Threading.Tasks; 5 | 6 | namespace Benchmarks 7 | { 8 | public class Benchmark 9 | { 10 | public Benchmark(string title, string description, Func methodToBench) 11 | { 12 | this.Title = title; 13 | this.Description = description; 14 | this.MethodToBench = methodToBench; 15 | this.Results = new List(); 16 | } 17 | 18 | public string Title { get; } 19 | 20 | public string Description { get; } 21 | 22 | public Func MethodToBench{ get; } 23 | 24 | public List Results { get; } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/RestLess.Benchmarks.Core/BenchmarkHttpMessageHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Net.Http; 4 | using System.Text; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | 8 | namespace Benchmarks 9 | { 10 | public class BenchmarkHttpMessageHandler : HttpMessageHandler 11 | { 12 | protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 13 | { 14 | HttpResponseMessage responseMessage = new HttpResponseMessage() 15 | { 16 | Content = new StringContent("hello benchmark") 17 | }; 18 | 19 | return Task.FromResult(responseMessage); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/RestLess.Benchmarks.Core/BenchmarkResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Benchmarks 6 | { 7 | public class BenchmarkResult 8 | { 9 | public BenchmarkResult(string libName, long elapsedMilliseconds) 10 | { 11 | this.LibName = libName; 12 | this.ElapsedMilliseconds = elapsedMilliseconds; 13 | } 14 | 15 | public string LibName { get; } 16 | 17 | public long ElapsedMilliseconds { get; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/RestLess.Benchmarks.Core/Benchmarker.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Net.Http; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using Benchmarks.PerformanceTesters; 8 | 9 | namespace Benchmarks 10 | { 11 | public class Benchmarker 12 | { 13 | private readonly Stopwatch swatch; 14 | private readonly PerformanceTester[] performanceTesters; 15 | private readonly Benchmark[] benchmarks; 16 | private readonly HttpClient httpClient; 17 | 18 | private const int RequestCount = 1000; 19 | 20 | public Benchmarker() 21 | { 22 | this.swatch = new Stopwatch(); 23 | this.httpClient = new HttpClient(new BenchmarkHttpMessageHandler()) 24 | { 25 | BaseAddress = new Uri("http://www.benchmark.com") 26 | }; 27 | 28 | this.performanceTesters = new PerformanceTester[] 29 | { 30 | new RefitPerformanceTester(this.httpClient), 31 | new RestLessPerformanceTester(this.httpClient) 32 | }; 33 | 34 | this.benchmarks = new Benchmark[] 35 | { 36 | new Benchmark("Startup and one request","The startup time and the time to process one request.",x => x.StartupAndOneRequestAsync()), 37 | new Benchmark($"{RequestCount} requests",$"The time to process {RequestCount} requests",x => x.MultipleSimpleRequestsAsync(RequestCount)), 38 | new Benchmark($"{RequestCount} requests with dictionary",$"The time to process {RequestCount} requests with a dicitonary query parameter",x => x.MultipleDictionaryRequestsAsync(RequestCount)) 39 | }; 40 | } 41 | 42 | public async Task> RunAsync() 43 | { 44 | for (int i = 0; i < this.benchmarks.Length; i++) 45 | { 46 | await this.ExecuteBenchmarkAsync(this.benchmarks[i]); 47 | } 48 | return this.benchmarks; 49 | } 50 | 51 | private async Task ExecuteBenchmarkAsync(Benchmark benchmark) 52 | { 53 | Console.WriteLine($"Benchmark: {benchmark.Title}"); 54 | for (int i = 0; i < this.performanceTesters.Length; i++) 55 | { 56 | var benchmarkResult = await this.ExecuteMethodToBenchAsync(benchmark.MethodToBench, this.performanceTesters[i]); 57 | benchmark.Results.Add(benchmarkResult); 58 | } 59 | Console.WriteLine(); 60 | } 61 | 62 | private async Task ExecuteMethodToBenchAsync(Func methodToBench, PerformanceTester performanceTester) 63 | { 64 | this.swatch.Restart(); 65 | await methodToBench(performanceTester); 66 | this.swatch.Stop(); 67 | Console.WriteLine($"{performanceTester.LibName}: {this.swatch.ElapsedMilliseconds}ms"); 68 | return new BenchmarkResult(performanceTester.LibName, this.swatch.ElapsedMilliseconds); 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/RestLess.Benchmarks.Core/PerformanceTesters/PerformanceTester.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Net.Http; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Benchmarks 8 | { 9 | public abstract class PerformanceTester 10 | { 11 | public const string Path = "/v1"; 12 | public const string Query = "all"; 13 | protected readonly HttpClient httpClient; 14 | protected readonly Dictionary dictionary; 15 | 16 | protected PerformanceTester(string libName, HttpClient httpClient) 17 | { 18 | this.LibName = libName; 19 | this.httpClient = httpClient; 20 | this.dictionary = new Dictionary 21 | { 22 | ["order"] = "desc", 23 | ["limit"] = "1", 24 | ["skip"] = "100", 25 | }; 26 | } 27 | 28 | public string LibName { get; } 29 | 30 | public async Task StartupAndOneRequestAsync() 31 | { 32 | this.CreateImplementation(this.httpClient); 33 | await this.ExecuteOneSimpleRequestAsync(); 34 | } 35 | 36 | public Task MultipleSimpleRequestsAsync(int requestCount) 37 | { 38 | return this.MultipleRequestAsync(requestCount, this.ExecuteOneSimpleRequestAsync); 39 | } 40 | 41 | public Task MultipleDictionaryRequestsAsync(int requestCount) 42 | { 43 | return this.MultipleRequestAsync(requestCount, this.ExecuteOneDictionaryRequestAsync); 44 | } 45 | 46 | private async Task MultipleRequestAsync(int requestCount, Func methodToExecute) 47 | { 48 | for (int i = 0; i < requestCount; i++) 49 | { 50 | await methodToExecute(); 51 | } 52 | } 53 | 54 | protected abstract void CreateImplementation(HttpClient httpClient); 55 | 56 | protected abstract Task ExecuteOneSimpleRequestAsync(); 57 | 58 | protected abstract Task ExecuteOneDictionaryRequestAsync(); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/RestLess.Benchmarks.Core/PerformanceTesters/RefitPerformanceTester.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Net.Http; 3 | using System.Reflection; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Benchmarks.Interfaces; 7 | using Refit; 8 | 9 | namespace Benchmarks.PerformanceTesters 10 | { 11 | public class RefitPerformanceTester : PerformanceTester 12 | { 13 | private IRefitApi api; 14 | 15 | public RefitPerformanceTester(HttpClient httpClient) : base("Refit", httpClient) 16 | { 17 | } 18 | 19 | protected override void CreateImplementation(HttpClient httpClient) 20 | { 21 | this.api = RestService.For(httpClient, new RefitSettings { UrlParameterFormatter = new UrlParameterFormatter() }); 22 | } 23 | 24 | protected override Task ExecuteOneDictionaryRequestAsync() 25 | { 26 | return this.api.GetStringWithDictionaryAsync(this.dictionary); 27 | } 28 | 29 | protected override Task ExecuteOneSimpleRequestAsync() 30 | { 31 | return this.api.GetString00Async(Path, Query); 32 | } 33 | 34 | private class UrlParameterFormatter : IUrlParameterFormatter 35 | { 36 | public string Format(object value, ParameterInfo parameterInfo) 37 | { 38 | if (value is IEnumerable> dictionary) 39 | { 40 | StringBuilder str = new StringBuilder(); 41 | foreach (var item in dictionary) 42 | { 43 | str.Append($"{item.Key}={item.Value.ToString()}&"); 44 | } 45 | str.Remove(str.Length - 1, 1); 46 | return str.ToString(); 47 | } 48 | else 49 | { 50 | return value?.ToString(); 51 | } 52 | } 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/RestLess.Benchmarks.Core/PerformanceTesters/RestLessPerformanceTester.cs: -------------------------------------------------------------------------------- 1 | using System.Net.Http; 2 | using System.Threading.Tasks; 3 | using Benchmarks.Interfaces; 4 | using RestLess; 5 | 6 | namespace Benchmarks.PerformanceTesters 7 | { 8 | public class RestLessPerformanceTester : PerformanceTester 9 | { 10 | private IRestLessApi api; 11 | 12 | public RestLessPerformanceTester(HttpClient httpClient) : base("RestLess", httpClient) 13 | { 14 | } 15 | 16 | protected override void CreateImplementation(HttpClient httpClient) 17 | { 18 | this.api = RestClient.For(httpClient); 19 | } 20 | 21 | protected override Task ExecuteOneDictionaryRequestAsync() 22 | { 23 | return this.api.GetStringWithDictionaryAsync(this.dictionary); 24 | } 25 | 26 | protected override Task ExecuteOneSimpleRequestAsync() 27 | { 28 | return this.api.GetString00Async(Path, Query); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/RestLess.Benchmarks.Core/RestLess.Benchmarks.Core.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard1.4 5 | Benchmarks 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/RestLess.Benchmarks.Droid/Assets/AboutAssets.txt: -------------------------------------------------------------------------------- 1 | Any raw assets you want to be deployed with your application can be placed in 2 | this directory (and child directories) and given a Build Action of "AndroidAsset". 3 | 4 | These files will be deployed with you package and will be accessible using Android's 5 | AssetManager, like this: 6 | 7 | public class ReadAsset : Activity 8 | { 9 | protected override void OnCreate (Bundle bundle) 10 | { 11 | base.OnCreate (bundle); 12 | 13 | InputStream input = Assets.Open ("my_asset.txt"); 14 | } 15 | } 16 | 17 | Additionally, some Android functions will automatically load asset files: 18 | 19 | Typeface tf = Typeface.CreateFromAsset (Context.Assets, "fonts/samplefont.ttf"); -------------------------------------------------------------------------------- /src/RestLess.Benchmarks.Droid/GettingStarted.Xamarin: -------------------------------------------------------------------------------- 1 | 2 | GS\Android\CS\AndroidApp\GettingStarted.html 3 | false 4 | -------------------------------------------------------------------------------- /src/RestLess.Benchmarks.Droid/MainActivity.cs: -------------------------------------------------------------------------------- 1 | using Android.App; 2 | using Android.Widget; 3 | using Android.OS; 4 | using Microcharts; 5 | using SkiaSharp; 6 | using Microcharts.Droid; 7 | using Benchmarks; 8 | using System.Collections.Generic; 9 | using System.Linq; 10 | using Android.Support.V7.Widget; 11 | using Android.Views; 12 | 13 | namespace RestLess.Benchmarks.Droid 14 | { 15 | [Activity(Label = "RestLess.Benchmarks.Droid", MainLauncher = true)] 16 | public class MainActivity : Activity 17 | { 18 | private static readonly Dictionary LibNameToColor = new Dictionary 19 | { 20 | ["Refit"] = "#266489", 21 | ["RestLess"] = "#90D585", 22 | }; 23 | 24 | private RecyclerView recyclerView; 25 | 26 | protected override void OnCreate(Bundle savedInstanceState) 27 | { 28 | base.OnCreate(savedInstanceState); 29 | 30 | // Set our view from the "main" layout resource 31 | SetContentView(Resource.Layout.Main); 32 | 33 | var button = this.FindViewById