├── .gitignore
├── ConsoleApp2
├── ConsoleApp2.csproj
└── Program.cs
├── README.md
├── RestSharpPolly.Test
├── RestSharpPolly.Test.csproj
└── UnitTest1.cs
├── RestSharpPolly.sln
└── RestSharpPolly
├── PolicyProviders
├── TimeoutAndRetryAsyncPolicy.cs
└── TimeoutAndRetryPolicy.cs
├── RestClientBase.cs
├── RestClientFactory.cs
├── RestClientFactoryGeneric.cs
├── RestReqExt.cs
└── RestSharpPolly.csproj
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 | ##
4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
5 |
6 | # User-specific files
7 | *.suo
8 | *.user
9 | *.userosscache
10 | *.sln.docstates
11 |
12 | # User-specific files (MonoDevelop/Xamarin Studio)
13 | *.userprefs
14 |
15 | # Build results
16 | [Dd]ebug/
17 | [Dd]ebugPublic/
18 | [Rr]elease/
19 | [Rr]eleases/
20 | x64/
21 | x86/
22 | bld/
23 | [Bb]in/
24 | [Oo]bj/
25 | [Ll]og/
26 |
27 | # Visual Studio 2015 cache/options directory
28 | .vs/
29 | # Uncomment if you have tasks that create the project's static files in wwwroot
30 | #wwwroot/
31 |
32 | # MSTest test Results
33 | [Tt]est[Rr]esult*/
34 | [Bb]uild[Ll]og.*
35 |
36 | # NUNIT
37 | *.VisualState.xml
38 | TestResult.xml
39 |
40 | # Build Results of an ATL Project
41 | [Dd]ebugPS/
42 | [Rr]eleasePS/
43 | dlldata.c
44 |
45 | # .NET Core
46 | project.lock.json
47 | project.fragment.lock.json
48 | artifacts/
49 | **/Properties/launchSettings.json
50 |
51 | *_i.c
52 | *_p.c
53 | *_i.h
54 | *.ilk
55 | *.meta
56 | *.obj
57 | *.pch
58 | *.pdb
59 | *.pgc
60 | *.pgd
61 | *.rsp
62 | *.sbr
63 | *.tlb
64 | *.tli
65 | *.tlh
66 | *.tmp
67 | *.tmp_proj
68 | *.log
69 | *.vspscc
70 | *.vssscc
71 | .builds
72 | *.pidb
73 | *.svclog
74 | *.scc
75 |
76 | # Chutzpah Test files
77 | _Chutzpah*
78 |
79 | # Visual C++ cache files
80 | ipch/
81 | *.aps
82 | *.ncb
83 | *.opendb
84 | *.opensdf
85 | *.sdf
86 | *.cachefile
87 | *.VC.db
88 | *.VC.VC.opendb
89 |
90 | # Visual Studio profiler
91 | *.psess
92 | *.vsp
93 | *.vspx
94 | *.sap
95 |
96 | # TFS 2012 Local Workspace
97 | $tf/
98 |
99 | # Guidance Automation Toolkit
100 | *.gpState
101 |
102 | # ReSharper is a .NET coding add-in
103 | _ReSharper*/
104 | *.[Rr]e[Ss]harper
105 | *.DotSettings.user
106 |
107 | # JustCode is a .NET coding add-in
108 | .JustCode
109 |
110 | # TeamCity is a build add-in
111 | _TeamCity*
112 |
113 | # DotCover is a Code Coverage Tool
114 | *.dotCover
115 |
116 | # Visual Studio code coverage results
117 | *.coverage
118 | *.coveragexml
119 |
120 | # NCrunch
121 | _NCrunch_*
122 | .*crunch*.local.xml
123 | nCrunchTemp_*
124 |
125 | # MightyMoose
126 | *.mm.*
127 | AutoTest.Net/
128 |
129 | # Web workbench (sass)
130 | .sass-cache/
131 |
132 | # Installshield output folder
133 | [Ee]xpress/
134 |
135 | # DocProject is a documentation generator add-in
136 | DocProject/buildhelp/
137 | DocProject/Help/*.HxT
138 | DocProject/Help/*.HxC
139 | DocProject/Help/*.hhc
140 | DocProject/Help/*.hhk
141 | DocProject/Help/*.hhp
142 | DocProject/Help/Html2
143 | DocProject/Help/html
144 |
145 | # Click-Once directory
146 | publish/
147 |
148 | # Publish Web Output
149 | *.[Pp]ublish.xml
150 | *.azurePubxml
151 | # TODO: Comment the next line if you want to checkin your web deploy settings
152 | # but database connection strings (with potential passwords) will be unencrypted
153 | *.pubxml
154 | *.publishproj
155 |
156 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
157 | # checkin your Azure Web App publish settings, but sensitive information contained
158 | # in these scripts will be unencrypted
159 | PublishScripts/
160 |
161 | # NuGet Packages
162 | *.nupkg
163 | # The packages folder can be ignored because of Package Restore
164 | **/packages/*
165 | # except build/, which is used as an MSBuild target.
166 | !**/packages/build/
167 | # Uncomment if necessary however generally it will be regenerated when needed
168 | #!**/packages/repositories.config
169 | # NuGet v3's project.json files produces more ignorable files
170 | *.nuget.props
171 | *.nuget.targets
172 |
173 | # Microsoft Azure Build Output
174 | csx/
175 | *.build.csdef
176 |
177 | # Microsoft Azure Emulator
178 | ecf/
179 | rcf/
180 |
181 | # Windows Store app package directories and files
182 | AppPackages/
183 | BundleArtifacts/
184 | Package.StoreAssociation.xml
185 | _pkginfo.txt
186 |
187 | # Visual Studio cache files
188 | # files ending in .cache can be ignored
189 | *.[Cc]ache
190 | # but keep track of directories ending in .cache
191 | !*.[Cc]ache/
192 |
193 | # Others
194 | ClientBin/
195 | ~$*
196 | *~
197 | *.dbmdl
198 | *.dbproj.schemaview
199 | *.jfm
200 | *.pfx
201 | *.publishsettings
202 | orleans.codegen.cs
203 |
204 | # Since there are multiple workflows, uncomment next line to ignore bower_components
205 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
206 | #bower_components/
207 |
208 | # RIA/Silverlight projects
209 | Generated_Code/
210 |
211 | # Backup & report files from converting an old project file
212 | # to a newer Visual Studio version. Backup files are not needed,
213 | # because we have git ;-)
214 | _UpgradeReport_Files/
215 | Backup*/
216 | UpgradeLog*.XML
217 | UpgradeLog*.htm
218 |
219 | # SQL Server files
220 | *.mdf
221 | *.ldf
222 | *.ndf
223 |
224 | # Business Intelligence projects
225 | *.rdl.data
226 | *.bim.layout
227 | *.bim_*.settings
228 |
229 | # Microsoft Fakes
230 | FakesAssemblies/
231 |
232 | # GhostDoc plugin setting file
233 | *.GhostDoc.xml
234 |
235 | # Node.js Tools for Visual Studio
236 | .ntvs_analysis.dat
237 | node_modules/
238 |
239 | # Typescript v1 declaration files
240 | typings/
241 |
242 | # Visual Studio 6 build log
243 | *.plg
244 |
245 | # Visual Studio 6 workspace options file
246 | *.opt
247 |
248 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
249 | *.vbw
250 |
251 | # Visual Studio LightSwitch build output
252 | **/*.HTMLClient/GeneratedArtifacts
253 | **/*.DesktopClient/GeneratedArtifacts
254 | **/*.DesktopClient/ModelManifest.xml
255 | **/*.Server/GeneratedArtifacts
256 | **/*.Server/ModelManifest.xml
257 | _Pvt_Extensions
258 |
259 | # Paket dependency manager
260 | .paket/paket.exe
261 | paket-files/
262 |
263 | # FAKE - F# Make
264 | .fake/
265 |
266 | # JetBrains Rider
267 | .idea/
268 | *.sln.iml
269 |
270 | # CodeRush
271 | .cr/
272 |
273 | # Python Tools for Visual Studio (PTVS)
274 | __pycache__/
275 | *.pyc
276 |
277 | # Cake - Uncomment if you are using it
278 | # tools/**
279 | # !tools/packages.config
280 |
281 | # Telerik's JustMock configuration file
282 | *.jmconfig
283 |
284 | # BizTalk build output
285 | *.btp.cs
286 | *.btm.cs
287 | *.odx.cs
288 | *.xsd.cs
289 |
--------------------------------------------------------------------------------
/ConsoleApp2/ConsoleApp2.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp3.1
6 | latest
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/ConsoleApp2/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Net;
3 | using System.Net.Http;
4 | using System.Net.WebSockets;
5 | using System.Threading.Tasks;
6 | using RestSharpPolly;
7 | using RestSharpPolly.PolicyProviders;
8 | using Newtonsoft.Json;
9 | using Polly;
10 | using Polly.Timeout;
11 | using RestSharp;
12 | using Serilog;
13 |
14 | namespace ConsoleApp2
15 | {
16 |
17 | ///
18 | /// see response content from https://httpstat.us/500
19 | ///
20 | public class QueryResultModel
21 | {
22 |
23 | [JsonProperty("code")]
24 | public int code { get; set; }
25 |
26 | [JsonProperty("description")]
27 | public string description { get; set; }
28 | }
29 |
30 | internal static class Program
31 | {
32 | private static int re = 0;
33 |
34 | private static async Task Main(string[] args)
35 | {
36 | // To uncomment to try
37 |
38 | //async
39 | var asyncPolicy2 = BuildTimeoutAndRetryAsyncPolicy2(3, 2, 10);
40 | var client1 = RestClientFactory.Create(asyncPolicy2);
41 | var request1 = new RestRequest(Method.GET);
42 | client1.BaseUrl = new Uri("https://httpstat.us/500");
43 | var response5 = await client1.ExecuteAsync(request1);
44 | Console.ReadKey();
45 |
46 |
47 | ////// To uncomment to try
48 | ////////async (no result)
49 | //////////https://github.com/App-vNext/Polly/wiki/Non-generic-and-generic-policies
50 | //var noResultAyncPolicy = BuildTimeoutAndRetryAsyncPolicy(3, 2, 10); ;
51 |
52 | //var client2Async = RestClientFactory.Create(noResultAyncPolicy);
53 | //client2Async.BaseUrl = new Uri("https://httpstat.us/200?sleep=15000");
54 | //var request2 = new RestRequest(Method.GET);
55 | ////if runtime have errors ,it will retry.
56 | //var response2 = await client2Async.ExecuteAsync(request2);
57 | //Console.ReadKey();
58 |
59 | ////// To uncomment to try
60 | //////async
61 | //var noResultaAyncPolicyT = BuildTimeoutAndRetryAsyncPolicy3(3, 2, 10);
62 | //var client2Async = RestClientFactory>.Create(noResultaAyncPolicyT);
63 | //client2Async.BaseUrl = new Uri("https://httpstat.us/500");
64 | //var request3 = new RestRequest(Method.GET);
65 | ////if runtime have errors ,it will retry.
66 | //var response6 = await client2Async.ExecuteAsync(request3);
67 | //Console.ReadKey();
68 |
69 | ////// To uncomment to try
70 | //////sync (no result)
71 | ////https://github.com/App-vNext/Polly/wiki/Non-generic-and-generic-policies
72 | //var syncPolicy2 = BuildTimeoutAndRetryPolicy(3, 2, 5);
73 | //var syncClient2 = RestClientFactory.Create(syncPolicy2);
74 | //var request2 = new RestRequest(Method.GET);
75 | //syncClient2.BaseUrl = new Uri("https://httpstat.us/200?sleep=15000");
76 | ////if runtime have errors ,it will retry.
77 | //var response4 = syncClient2.Execute(request2);
78 | //Console.ReadKey();
79 |
80 | //////sync
81 | //////To uncomment to try
82 | //var syncPolicy3 = BuildTimeoutAndRetryPolicy2(3, 2, 10);
83 | //var syncclient3 = RestClientFactory.Create(syncPolicy3);
84 | //var request4 = new RestRequest(Method.GET);
85 | //syncclient3.BaseUrl = new Uri("https://httpstat.us/500");
86 | ////if runtime have errors ,it will retry.
87 | //var res = syncclient3.Execute(request4);
88 | //Console.ReadKey();
89 |
90 | }
91 |
92 | public static ISyncPolicy BuildTimeoutAndRetryPolicy2(int retryNumber, int retrySleep, int timeoutSeconds)
93 | {
94 | var logger = new LoggerConfiguration().MinimumLevel.Verbose().Enrich.FromLogContext()
95 | .WriteTo.ColoredConsole().CreateLogger();
96 | var retry = Policy
97 | .Handle()
98 | .OrResult(r => r.StatusCode != HttpStatusCode.OK)
99 | .WaitAndRetry(retryNumber, retryAttempt => TimeSpan.FromMilliseconds(//ignore retrySleep, set to 5 seconds
100 | 5000), onRetry: (exception, calculatedWaitDuration) =>
101 | {
102 | re++;
103 | logger.Information(
104 | $"Policy logging onRetry {re.ToString()} times , response content is {exception.Result.Content}and error is :");
105 | Console.WriteLine("I am Console.WriteLine");
106 | });
107 |
108 | var timeout = Policy.Timeout(timeoutSeconds);
109 | return Policy.Wrap(retry, timeout);
110 | }
111 |
112 | public static ISyncPolicy BuildTimeoutAndRetryPolicy(int retryNumber, int retrySleep, int timeoutSeconds)
113 | {
114 | var logger = new LoggerConfiguration().MinimumLevel.Verbose().Enrich.FromLogContext()
115 | .WriteTo.ColoredConsole().CreateLogger();
116 | var timeoutPolicy = Policy
117 | .Timeout(
118 | TimeSpan.FromSeconds(timeoutSeconds),
119 | TimeoutStrategy.Optimistic,
120 | (context, timeout, _, exception) =>
121 | {
122 | Console.WriteLine($"{"Timeout",-10}{timeout,-10:ss\\.fff}: {exception.GetType().Name}");
123 |
124 | });
125 |
126 | var onRetryInner = new Action((e, i) =>
127 | {
128 |
129 | Console.WriteLine($"Retry #{i} due to exception '{(e.InnerException ?? e).Message}'");
130 |
131 | });
132 |
133 | var retryPolicy = Policy
134 | .Handle()
135 | .Retry(retryNumber, onRetryInner);
136 | return Policy.Wrap(timeoutPolicy, retryPolicy);
137 |
138 | }
139 |
140 | public static IAsyncPolicy BuildTimeoutAndRetryAsyncPolicy2(int retryNumber, int retrySleep, int timeoutSeconds)
141 | {
142 | var logger = new LoggerConfiguration().MinimumLevel.Verbose().Enrich.FromLogContext()
143 | .WriteTo.ColoredConsole().CreateLogger();
144 | var retry = Policy
145 | .Handle().Or()
146 | .OrResult(r => (int)r.StatusCode == 500)
147 | .WaitAndRetryAsync(retryNumber, retryAttempt => TimeSpan.FromMilliseconds(5000 * retryNumber * retrySleep),
148 | onRetry: (exception, calculatedWaitDuration) =>
149 | {
150 | re++;
151 | logger.Information($"Policy logging onRetry {re.ToString()} times , response content is {exception.Result.Content}and error is :");
152 | Console.WriteLine("I am Console.WriteLine");
153 | });
154 |
155 | var timeout = Policy.TimeoutAsync(timeoutSeconds);
156 | return Policy.WrapAsync(retry, timeout);
157 | }
158 |
159 | public static IAsyncPolicy> BuildTimeoutAndRetryAsyncPolicy3(int retryNumber, int retrySleep, int timeoutSeconds)
160 | {
161 | var logger = new LoggerConfiguration().MinimumLevel.Verbose().Enrich.FromLogContext()
162 | .WriteTo.ColoredConsole().CreateLogger();
163 | var retry = Policy
164 | .Handle()
165 | .OrResult>(r => (int)r.StatusCode == 500)
166 | .WaitAndRetryAsync(retryNumber, retryAttempt => TimeSpan.FromMilliseconds(5000 * retryNumber * retrySleep),
167 | onRetry: (exception, calculatedWaitDuration) =>
168 | {
169 | re++;
170 | logger.Information($"Policy logging onRetry {re.ToString()} times , response content is {exception.Result.Content}and error is :");
171 | Console.WriteLine("I am Console.WriteLine");
172 | });
173 |
174 | var timeout = Policy.TimeoutAsync>(timeoutSeconds);
175 |
176 | return Policy.WrapAsync(retry, timeout);
177 | }
178 |
179 | public static IAsyncPolicy BuildTimeoutAndRetryAsyncPolicy(int retryNumber, int retrySleep, int timeoutSeconds)
180 | {
181 | var logger = new LoggerConfiguration().MinimumLevel.Verbose().Enrich.FromLogContext()
182 | .WriteTo.ColoredConsole().CreateLogger();
183 |
184 | var timeoutPolicy = Policy
185 | .TimeoutAsync(
186 | TimeSpan.FromSeconds(timeoutSeconds),
187 | TimeoutStrategy.Pessimistic,
188 | (context, timeout, _, exception) =>
189 | {
190 | Console.WriteLine($"{"Timeout",-10}{timeout,-10:ss\\.fff}: {exception.GetType().Name}");
191 | return Task.CompletedTask;
192 | });
193 |
194 | var onRetryInner = new Func((e, i) =>
195 | {
196 | Console.WriteLine($"Retry #{i} due to exception '{(e.InnerException ?? e).Message}'");
197 | return Task.CompletedTask;
198 | });
199 |
200 | var retryPolicy = Policy
201 | .Handle()
202 | .RetryAsync(retryNumber, onRetryInner);
203 | return Policy.WrapAsync(retryPolicy, timeoutPolicy);
204 | }
205 |
206 |
207 | }
208 |
209 |
210 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # RestSharpPolly
2 | RestSharp with Polly
3 | Wrapping the RestClient with Polly framework.
4 | Usage:
5 |
6 | ```
7 | var client = RestClientFactory.Create(TimeoutAndRetryPolicy.Build(3, 10, 60));
8 | client.BaseUrl = new Uri("");
9 | var request = new RestRequest(Method.GET);
10 | request.AddJsonBody(model);
11 | var response = client.Execute(request);
12 | ```
13 | The class RestClientFactory is generic.
14 | ```
15 | RestClientFactory Create(ISyncPolicy syncPolicy)
16 | ```
17 |
18 |
19 |
20 | # Install
21 | Import RestSharpPolly into an existing project
22 |
23 | Go to the project folder of the application and install the Nuget package reference
24 |
25 | $ dotnet add package RestSharpPolly
26 |
27 |
28 | ID your project using the RestSharp v107, to checkout the branch **`V107`**
29 |
30 | in the v107 case,
31 |
32 | ``` var asyncPolicy2 = BuildTimeoutAndRetryAsyncPolicy2(3, 2, 10);
33 | var client1 = new RestClientFactory().Create(asyncPolicy2);
34 | var request1 = new RestRequest();
35 |
36 | client1.RestClientOptions.BaseUrl = new Uri("https://httpstat.us/500");
37 | var host = client1.Build(client1.RestClientOptions);
38 | var response5 = await host.ExecuteAsync(request1);
39 | Console.ReadKey();
40 | ```
41 |
42 | About v107 branch
43 |
44 | **NOT fully tested, Not recommended for production use unless you know what you're doing. :)**
45 | btw official RestSharp 107.3.0 is not compatible with .net45 /.net46 /.net47, so [RestSharpPolly](https://github.com/yuessir/RestSharpPolly) does not support for the frameworks.
46 |
47 |
48 |
49 | # Upgrading
50 |
51 | Simply `git pull` or `git rebase` the latest changes
52 |
53 |
--------------------------------------------------------------------------------
/RestSharpPolly.Test/RestSharpPolly.Test.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp3.1
5 |
6 | false
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/RestSharpPolly.Test/UnitTest1.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using System.Net;
4 | using Polly;
5 | using RestSharp;
6 | using Xunit;
7 |
8 | namespace RestSharpPolly.Test
9 | {
10 | /// A unit test 1, See console app
11 | public class UnitTest1
12 | {
13 | public static int count = 0;
14 | [Fact]
15 | public void Test1()
16 | {
17 | var policy = BuildTimeoutAndRetryPolicy(3, 1, 60);
18 | var client = RestClientFactory.Create(policy);
19 |
20 | client.BaseUrl = new Uri("https://httpstat.us/500");
21 | IRestRequest request = new RestRequest(Method.GET);
22 | //if runtime have errors ,it will retry.
23 |
24 | Assert.Throws(() => client.Execute(null));
25 | Assert.Equal(3, count);
26 | }
27 |
28 | public static ISyncPolicy BuildTimeoutAndRetryPolicy2(int retryNumber, int retrySleep, int timeoutSeconds)
29 | {
30 |
31 | var retry = Policy
32 | .Handle()
33 | .OrResult(r => r.StatusCode != HttpStatusCode.OK)
34 | .WaitAndRetry(retryNumber, retryAttempt => TimeSpan.FromMilliseconds(//ignore retrySleep, set to 5 seconds
35 | 5000), onRetry: (exception, calculatedWaitDuration) =>
36 | {
37 | count++;
38 | Console.WriteLine("I am Console.WriteLine");
39 | });
40 |
41 | var timeout = Policy.Timeout(timeoutSeconds);
42 | return Policy.Wrap(retry, timeout);
43 | }
44 |
45 | public static ISyncPolicy BuildTimeoutAndRetryPolicy(int retryNumber, int retrySleep, int timeoutSeconds)
46 | {
47 | count = 0;
48 | var retry = Policy
49 | .Handle().Or()
50 |
51 | .WaitAndRetry(retryNumber, retryAttempt => TimeSpan.FromMilliseconds(//ignore retrySleep, set to 5 seconds
52 | 5000), onRetry: (exception, calculatedWaitDuration) =>
53 | {
54 | count++;
55 | Console.WriteLine("I am Console.WriteLine");
56 | });
57 |
58 | var timeout = Policy.Timeout(timeoutSeconds);
59 | return Policy.Wrap(retry, timeout);
60 | }
61 | }
62 | }
--------------------------------------------------------------------------------
/RestSharpPolly.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.29709.97
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RestSharpPolly", "RestSharpPolly\RestSharpPolly.csproj", "{8716D9CF-BCDB-4CB5-BC33-F2BFC1802F72}"
7 | EndProject
8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RestSharpPolly.Test", "RestSharpPolly.Test\RestSharpPolly.Test.csproj", "{FBB7C57F-F878-4252-B642-A5BEAFEFB0F4}"
9 | EndProject
10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsoleApp2", "ConsoleApp2\ConsoleApp2.csproj", "{3ADAEB2F-233B-477A-9042-8A6B481E40E2}"
11 | EndProject
12 | Global
13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
14 | Debug|Any CPU = Debug|Any CPU
15 | Release|Any CPU = Release|Any CPU
16 | EndGlobalSection
17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
18 | {8716D9CF-BCDB-4CB5-BC33-F2BFC1802F72}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
19 | {8716D9CF-BCDB-4CB5-BC33-F2BFC1802F72}.Debug|Any CPU.Build.0 = Debug|Any CPU
20 | {8716D9CF-BCDB-4CB5-BC33-F2BFC1802F72}.Release|Any CPU.ActiveCfg = Release|Any CPU
21 | {8716D9CF-BCDB-4CB5-BC33-F2BFC1802F72}.Release|Any CPU.Build.0 = Release|Any CPU
22 | {FBB7C57F-F878-4252-B642-A5BEAFEFB0F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
23 | {FBB7C57F-F878-4252-B642-A5BEAFEFB0F4}.Debug|Any CPU.Build.0 = Debug|Any CPU
24 | {FBB7C57F-F878-4252-B642-A5BEAFEFB0F4}.Release|Any CPU.ActiveCfg = Release|Any CPU
25 | {FBB7C57F-F878-4252-B642-A5BEAFEFB0F4}.Release|Any CPU.Build.0 = Release|Any CPU
26 | {3ADAEB2F-233B-477A-9042-8A6B481E40E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
27 | {3ADAEB2F-233B-477A-9042-8A6B481E40E2}.Debug|Any CPU.Build.0 = Debug|Any CPU
28 | {3ADAEB2F-233B-477A-9042-8A6B481E40E2}.Release|Any CPU.ActiveCfg = Release|Any CPU
29 | {3ADAEB2F-233B-477A-9042-8A6B481E40E2}.Release|Any CPU.Build.0 = Release|Any CPU
30 | EndGlobalSection
31 | GlobalSection(SolutionProperties) = preSolution
32 | HideSolutionNode = FALSE
33 | EndGlobalSection
34 | GlobalSection(ExtensibilityGlobals) = postSolution
35 | SolutionGuid = {8FDC92BD-36E5-4C04-AA4D-AC27BC71AABC}
36 | EndGlobalSection
37 | EndGlobal
38 |
--------------------------------------------------------------------------------
/RestSharpPolly/PolicyProviders/TimeoutAndRetryAsyncPolicy.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Net;
3 | using Polly;
4 | using RestSharp;
5 |
6 | namespace RestSharpPolly.PolicyProviders
7 | {
8 | ///
9 | /// A timeout and retry policy.
10 | ///
11 | public class TimeoutAndRetryAsyncPolicy
12 | {
13 | public static IAsyncPolicy Build(int retryNumber, int retrySleep, int timeoutSeconds)
14 | {
15 | var retry = Policy
16 | .Handle()
17 | .OrResult(r => r.StatusCode != HttpStatusCode.OK)
18 | .WaitAndRetryAsync(retryNumber, retryAttempt => TimeSpan.FromMilliseconds(
19 | 5000 * retryNumber * retrySleep));
20 |
21 | var timeout = Policy.TimeoutAsync(timeoutSeconds);
22 | return Policy.WrapAsync(timeout, retry);
23 | }
24 | }
25 | }
--------------------------------------------------------------------------------
/RestSharpPolly/PolicyProviders/TimeoutAndRetryPolicy.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Net;
3 | using Polly;
4 | using RestSharp;
5 |
6 | namespace RestSharpPolly.PolicyProviders
7 | {
8 | ///
9 | /// A timeout and retry policy.
10 | ///
11 | public class TimeoutAndRetryPolicy
12 | {
13 | public static ISyncPolicy Build(int retryNumber, int retrySleep, int timeoutSeconds)
14 | {
15 | var retry = Policy
16 | .Handle()
17 | .OrResult(r => r.StatusCode != HttpStatusCode.OK)
18 | .WaitAndRetry(retryNumber, retryAttempt => TimeSpan.FromMilliseconds(
19 | 5000 * retryNumber * retrySleep));
20 |
21 | var timeout = Policy.Timeout(timeoutSeconds);
22 | return Policy.Wrap(retry, timeout);
23 | }
24 | }
25 | }
--------------------------------------------------------------------------------
/RestSharpPolly/RestClientBase.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Linq.Expressions;
5 | using System.Net;
6 | using System.Text;
7 | using System.Threading;
8 | using System.Threading.Tasks;
9 | using Polly;
10 | using RestSharp;
11 |
12 | namespace RestSharpPolly
13 | {
14 | public class RestClientBase
15 | {
16 | protected IRestClient _innerService { get; }
17 | protected RestClientBase(IRestClient innerService)
18 | {
19 | _innerService = innerService;
20 | }
21 | protected delegate IRestResponse RestClientCarrier(IRestClient client);
22 | protected delegate IRestResponse RestClientCarrier(IRestClient client);
23 | protected delegate Task> RestClientTaskCarrier(IRestClient client);
24 | protected delegate Task RestClientTaskCarrier(IRestClient client);
25 |
26 | protected delegate Task AsyncInterceptor(IRestRequest req, Func> exec);
27 | protected delegate Task> AsyncInterceptorT(IRestRequest req, Func>> exec);
28 | protected delegate IRestResponse SyncInterceptorT(IRestRequest req, Func> exec);
29 | protected delegate IRestResponse SyncInterceptor(IRestRequest req, Func exec);
30 |
31 |
32 | protected IRestResponse ExecutePolly(Expression methodLambda, IRestRequest request, ISyncPolicy policy)
33 |
34 | {
35 | return ExecuteImpl(methodLambda, request, (r, f) => request.GetPolicyResult(policy?.ExecuteAndCapture(f)));
36 | }
37 |
38 | protected IRestResponse ExecutePolly(Expression> methodLambda, IRestRequest request, ISyncPolicy policy)
39 | {
40 | return ExecuteImpl(methodLambda, request, (r, f) => request.GetPolicyResult(policy?.ExecuteAndCapture(f)));
41 | }
42 | private IRestResponse ExecuteImpl(Expression> methodLambda, IRestRequest request, SyncInterceptor interceptor)
43 | {
44 | var response = interceptor == null
45 | ? methodLambda.Compile().Invoke(_innerService)
46 | : interceptor.Invoke(request, () => methodLambda.Compile().Invoke(_innerService)) as IRestResponse;
47 |
48 | return response;
49 | }
50 | protected IRestResponse ExecutePolly(Expression methodLambda, IRestRequest request, ISyncPolicy policy)
51 | where TResult : IRestResponse
52 | {
53 | var innerpolicy = policy as ISyncPolicy;
54 | return ExecuteImpl(methodLambda, request, (r, f) => request.GetPolicyResult(innerpolicy?.ExecuteAndCapture(f)));
55 | }
56 |
57 | private IRestResponse ExecuteImpl(Expression methodLambda, IRestRequest request, SyncInterceptor interceptor)
58 | {
59 | var response = interceptor == null
60 | ? methodLambda.Compile().Invoke(_innerService)
61 | : interceptor.Invoke(request, () => methodLambda.Compile().Invoke(_innerService));
62 |
63 | return response;
64 | }
65 |
66 | protected IRestResponse ExecutePollyT(Expression methodLambda, IRestRequest request, ISyncPolicy policy)
67 | where T2 : IRestResponse
68 | {
69 | var innerpolicy = policy as ISyncPolicy>;
70 | return ExecuteImplT(methodLambda, request,
71 | (r, f) => request.GetPolicyResultT(innerpolicy?.ExecuteAndCapture(f)));
72 | }
73 |
74 | private IRestResponse ExecuteImplT(Expression methodLambda, IRestRequest request, SyncInterceptorT interceptor)
75 | {
76 | var response = interceptor == null
77 | ? (IRestResponse)methodLambda.Compile().Invoke(_innerService)
78 | : interceptor.Invoke(request, () => (IRestResponse)methodLambda.Compile().Invoke(_innerService));
79 |
80 | return response;
81 | }
82 |
83 |
84 | //async
85 | protected async Task ExecutePollyAsync(Expression methodLambda, IRestRequest request, IAsyncPolicy policy)
86 | {
87 | return await ExecuteImplAsync(methodLambda, request, (r, f) => request.GetPolicyTaskResult(policy.ExecuteAndCaptureAsync(f)));
88 | }
89 | //async
90 | protected async Task ExecutePollyAsync(Expression methodLambda, IRestRequest request, IAsyncPolicy policy)
91 | {
92 | var innerpolicy = policy as IAsyncPolicy;
93 | return await ExecuteImplAsync(methodLambda, request,
94 | (r, f) => request.GetPolicyTaskResult(innerpolicy?.ExecuteAndCaptureAsync(f)));
95 | }
96 |
97 | protected async Task> ExecutePollyTAsync(Expression> methodLambda, IRestRequest request, IAsyncPolicy policy)
98 | {
99 | return await ExecuteImplTAsync(methodLambda, request,
100 | (r, f) => request.GetPolicyTaskResultT(policy?.ExecuteAndCaptureAsync((f))));
101 | }
102 | private async Task ExecuteImplAsync(Expression methodLambda, IRestRequest request, AsyncInterceptor interceptor)
103 | {
104 |
105 | var response = interceptor == null
106 | ? await methodLambda.Compile().Invoke(_innerService)
107 | : await interceptor.Invoke(request, () => methodLambda.Compile().Invoke(_innerService));
108 |
109 | return response;
110 | }
111 |
112 | //async
113 | protected async Task> ExecutePollyTAsync(Expression> methodLambda, IRestRequest request, IAsyncPolicy policy)
114 | where T2 : IRestResponse
115 | {
116 | var innerpolicy = policy as IAsyncPolicy>;
117 | return await ExecuteImplTAsync(methodLambda, request,
118 | (r, f) => request.GetPolicyTaskResultT(innerpolicy?.ExecuteAndCaptureAsync((f))));
119 | }
120 | private async Task> ExecuteImplTAsync(Expression> methodLambda, IRestRequest request, AsyncInterceptorT interceptor)
121 | {
122 | var response = interceptor == null
123 | ? await methodLambda.Compile().Invoke(_innerService)
124 | : await interceptor.Invoke(request, () => methodLambda.Compile().Invoke(_innerService));
125 |
126 | return response;
127 | }
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/RestSharpPolly/RestClientFactory.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Net;
4 | using System.Net.Cache;
5 | using System.Net.Security;
6 | using System.Security.Cryptography.X509Certificates;
7 | using System.Text;
8 | using System.Threading;
9 | using System.Threading.Tasks;
10 | using Polly;
11 | using RestSharp;
12 | using RestSharp.Authenticators;
13 | using RestSharp.Deserializers;
14 | using RestSharp.Serialization;
15 |
16 | namespace RestSharpPolly
17 | {
18 | ///
19 | /// A REST client factory.
20 | ///
21 | public class RestClientFactory : RestClientBase, IRestClient
22 | {
23 | private static readonly Lazy LazyRestFac = new Lazy(() => new RestClientFactory());
24 | private static readonly Lazy LazyRestClient = new Lazy(() => new RestClient());
25 | private ISyncPolicy _pollyRetPolicy;
26 | private IAsyncPolicy _pollyRetAsyncPolicy;
27 | private static RestClientFactory InstanceRestClient => LazyRestFac.Value;
28 | private static IRestClient _innerService => LazyRestClient.Value;
29 |
30 | private RestClientFactory() : base(_innerService)
31 | {
32 | }
33 |
34 | public static IRestClient Create()
35 | {
36 | return _innerService;
37 | }
38 |
39 | public static RestClientFactory Create(ISyncPolicy syncPolicy)
40 | {
41 | return InstanceRestClient.SetPolicy(syncPolicy);
42 | }
43 |
44 | public static RestClientFactory Create(IAsyncPolicy asyncPolicy)
45 | {
46 | return InstanceRestClient.SetAsyncPolicy(asyncPolicy);
47 | }
48 |
49 | private RestClientFactory SetPolicy(ISyncPolicy syncPolicy)
50 | {
51 | _pollyRetPolicy = syncPolicy;
52 | return InstanceRestClient;
53 | }
54 |
55 | private RestClientFactory SetAsyncPolicy(IAsyncPolicy asyncPolicy)
56 | {
57 | _pollyRetAsyncPolicy = asyncPolicy;
58 | return InstanceRestClient;
59 | }
60 |
61 | public IRestClient UseSerializer(Func serializerFactory)
62 | {
63 | return _innerService.UseSerializer(serializerFactory);
64 | }
65 |
66 | public IRestClient UseSerializer() where T : IRestSerializer, new()
67 | {
68 | return _innerService.UseSerializer();
69 | }
70 |
71 | public IRestResponse Deserialize(IRestResponse response)
72 | {
73 | return _innerService.Deserialize(response);
74 | }
75 |
76 | public IRestClient UseUrlEncoder(Func encoder)
77 | {
78 | return _innerService.UseUrlEncoder(encoder);
79 | }
80 |
81 | public IRestClient UseQueryEncoder(Func queryEncoder)
82 | {
83 | return _innerService.UseQueryEncoder(queryEncoder);
84 | }
85 |
86 | public IRestResponse Execute(IRestRequest request)
87 | {
88 | if (null == request)
89 | throw new AggregateException(nameof(request) + " is null");
90 | return ExecutePolly(x => x.Execute(request), request, _pollyRetPolicy);
91 |
92 | }
93 |
94 | public IRestResponse Execute(IRestRequest request, Method httpMethod)
95 | {
96 | if (null == request)
97 | throw new AggregateException(nameof(request) + " is null");
98 | return ExecutePolly(x => x.Execute(request, httpMethod), request, _pollyRetPolicy);
99 |
100 | }
101 |
102 | public IRestResponse Execute(IRestRequest request)
103 | {
104 | if (null == request)
105 | throw new AggregateException(nameof(request) + " is null");
106 | return ExecutePolly(x => x.Execute(request), request, _pollyRetPolicy);
107 |
108 |
109 | }
110 |
111 | public IRestResponse Execute(IRestRequest request, Method httpMethod)
112 | {
113 | if (null == request)
114 | throw new AggregateException(nameof(request) + " is null");
115 | return ExecutePolly(x => x.Execute(request, httpMethod), request, _pollyRetPolicy);
116 |
117 | }
118 |
119 | public byte[] DownloadData(IRestRequest request)
120 | {
121 | return _innerService.DownloadData(request);
122 | }
123 |
124 | public Uri BuildUri(IRestRequest request)
125 | {
126 | return _innerService.BuildUri(request);
127 | }
128 |
129 | public string BuildUriWithoutQueryParameters(IRestRequest request)
130 | {
131 | return _innerService.BuildUriWithoutQueryParameters(request);
132 | }
133 |
134 | public void ConfigureWebRequest(Action configurator)
135 | {
136 | _innerService.ConfigureWebRequest(configurator);
137 | }
138 |
139 | public void AddHandler(string contentType, Func deserializerFactory)
140 | {
141 | _innerService.AddHandler(contentType, deserializerFactory);
142 | }
143 |
144 | public void RemoveHandler(string contentType)
145 | {
146 | _innerService.RemoveHandler(contentType);
147 | }
148 |
149 | public void ClearHandlers()
150 | {
151 | _innerService.ClearHandlers();
152 | }
153 |
154 | public IRestResponse ExecuteAsGet(IRestRequest request, string httpMethod)
155 | {
156 | if (null == request)
157 | throw new AggregateException(nameof(request) + " is null");
158 | return ExecutePolly(x => x.ExecuteAsGet(request, httpMethod), request, _pollyRetPolicy);
159 |
160 | }
161 |
162 | public IRestResponse ExecuteAsPost(IRestRequest request, string httpMethod)
163 | {
164 | if (null == request)
165 | throw new AggregateException(nameof(request) + " is null");
166 | return ExecutePolly(x => x.ExecuteAsPost(request, httpMethod), request, _pollyRetPolicy);
167 |
168 | }
169 |
170 | public IRestResponse ExecuteAsGet(IRestRequest request, string httpMethod)
171 | {
172 | if (null == request)
173 | throw new AggregateException(nameof(request) + " is null");
174 | return ExecutePolly(x => x.ExecuteAsGet(request, httpMethod), request, _pollyRetPolicy);
175 |
176 | }
177 |
178 | public IRestResponse ExecuteAsPost(IRestRequest request, string httpMethod)
179 | {
180 | if (null == request)
181 | throw new AggregateException(nameof(request) + " is null");
182 | return ExecutePolly(x => x.ExecuteAsPost(request, httpMethod), request, _pollyRetPolicy);
183 |
184 | }
185 |
186 | public async Task> ExecuteAsync(IRestRequest request, CancellationToken cancellationToken = new CancellationToken())
187 | {
188 | if (null == request)
189 | throw new AggregateException(nameof(request) + " is null");
190 | return await ExecutePollyTAsync(x =>
191 | x.ExecuteAsync(request, cancellationToken), request, _pollyRetAsyncPolicy);
192 |
193 | }
194 |
195 | public async Task> ExecuteAsync(IRestRequest request, Method httpMethod, CancellationToken cancellationToken = new CancellationToken())
196 | {
197 | if (null == request)
198 | throw new AggregateException(nameof(request) + " is null");
199 | return await ExecutePollyTAsync(x =>
200 | x.ExecuteAsync(request, httpMethod, cancellationToken), request, _pollyRetAsyncPolicy);
201 |
202 | }
203 |
204 | public async Task ExecuteAsync(IRestRequest request, Method httpMethod, CancellationToken cancellationToken = new CancellationToken())
205 | {
206 | if (null == request)
207 | throw new AggregateException(nameof(request) + " is null");
208 | return await ExecutePollyAsync(x =>
209 | x.ExecuteAsync(request, httpMethod, cancellationToken), request, _pollyRetAsyncPolicy);
210 |
211 | }
212 |
213 | public async Task ExecuteAsync(IRestRequest request, CancellationToken cancellationToken = new CancellationToken())
214 | {
215 | if (null == request)
216 | throw new AggregateException(nameof(request) + " is null");
217 | return await ExecutePollyAsync(x =>
218 | x.ExecuteAsync(request, cancellationToken), request, _pollyRetAsyncPolicy);
219 |
220 | }
221 |
222 | public async Task> ExecuteGetAsync(IRestRequest request, CancellationToken cancellationToken = new CancellationToken())
223 | {
224 | if (null == request)
225 | throw new AggregateException(nameof(request) + " is null");
226 | return await ExecutePollyTAsync(x =>
227 | x.ExecuteGetAsync(request, cancellationToken), request, _pollyRetAsyncPolicy);
228 |
229 | }
230 |
231 | public async Task> ExecutePostAsync(IRestRequest request, CancellationToken cancellationToken = new CancellationToken())
232 | {
233 | if (null == request)
234 | throw new AggregateException(nameof(request) + " is null");
235 | return await ExecutePollyTAsync(x =>
236 | x.ExecutePostAsync(request, cancellationToken), request, _pollyRetAsyncPolicy);
237 |
238 | }
239 |
240 | public async Task ExecuteGetAsync(IRestRequest request, CancellationToken cancellationToken = new CancellationToken())
241 | {
242 | if (null == request)
243 | throw new AggregateException(nameof(request) + " is null");
244 | return await ExecutePollyAsync(x =>
245 | x.ExecuteGetAsync(request, cancellationToken), request, _pollyRetAsyncPolicy);
246 |
247 | }
248 |
249 | public async Task ExecutePostAsync(IRestRequest request, CancellationToken cancellationToken = new CancellationToken())
250 | {
251 | if (null == request)
252 | throw new AggregateException(nameof(request) + " is null");
253 | return await ExecutePollyAsync(x =>
254 | x.ExecutePostAsync(request, cancellationToken), request, _pollyRetAsyncPolicy);
255 |
256 | }
257 |
258 | public CookieContainer CookieContainer
259 | {
260 | get => _innerService.CookieContainer;
261 | set => _innerService.CookieContainer = value;
262 | }
263 |
264 | public bool AutomaticDecompression
265 | {
266 | get => _innerService.AutomaticDecompression;
267 | set => _innerService.AutomaticDecompression = value;
268 | }
269 |
270 | public int? MaxRedirects
271 | {
272 | get => _innerService.MaxRedirects;
273 | set => _innerService.MaxRedirects = value;
274 | }
275 |
276 | public string UserAgent
277 | {
278 | get => _innerService.UserAgent;
279 | set => _innerService.UserAgent = value;
280 | }
281 |
282 | public int Timeout
283 | {
284 | get => _innerService.Timeout;
285 | set => _innerService.Timeout = value;
286 | }
287 |
288 | public int ReadWriteTimeout
289 | {
290 | get => _innerService.ReadWriteTimeout;
291 | set => _innerService.ReadWriteTimeout = value;
292 | }
293 |
294 | public bool UseSynchronizationContext
295 | {
296 | get => _innerService.UseSynchronizationContext;
297 | set => _innerService.UseSynchronizationContext = value;
298 | }
299 |
300 | public IAuthenticator Authenticator
301 | {
302 | get => _innerService.Authenticator;
303 | set => _innerService.Authenticator = value;
304 | }
305 |
306 | public Uri BaseUrl
307 | {
308 | get => _innerService.BaseUrl;
309 | set => _innerService.BaseUrl = value;
310 | }
311 |
312 | public Encoding Encoding
313 | {
314 | get => _innerService.Encoding;
315 | set => _innerService.Encoding = value;
316 | }
317 |
318 | public bool ThrowOnDeserializationError
319 | {
320 | get => _innerService.ThrowOnDeserializationError;
321 | set => _innerService.ThrowOnDeserializationError = value;
322 | }
323 |
324 | public bool FailOnDeserializationError
325 | {
326 | get => _innerService.FailOnDeserializationError;
327 | set => _innerService.FailOnDeserializationError = value;
328 | }
329 |
330 | public bool ThrowOnAnyError
331 | {
332 | get => _innerService.ThrowOnAnyError;
333 | set => _innerService.ThrowOnAnyError = value;
334 | }
335 |
336 | public string ConnectionGroupName
337 | {
338 | get => _innerService.ConnectionGroupName;
339 | set => _innerService.ConnectionGroupName = value;
340 | }
341 |
342 | public bool PreAuthenticate
343 | {
344 | get => _innerService.PreAuthenticate;
345 | set => _innerService.PreAuthenticate = value;
346 | }
347 |
348 | public bool UnsafeAuthenticatedConnectionSharing
349 | {
350 | get => _innerService.UnsafeAuthenticatedConnectionSharing;
351 | set => _innerService.UnsafeAuthenticatedConnectionSharing = value;
352 | }
353 |
354 | public IList DefaultParameters => _innerService.DefaultParameters;
355 |
356 | public string BaseHost
357 | {
358 | get => _innerService.BaseHost;
359 | set => _innerService.BaseHost = value;
360 | }
361 |
362 | public bool AllowMultipleDefaultParametersWithSameName
363 | {
364 | get => _innerService.AllowMultipleDefaultParametersWithSameName;
365 | set => _innerService.AllowMultipleDefaultParametersWithSameName = value;
366 | }
367 |
368 | public X509CertificateCollection ClientCertificates
369 | {
370 | get => _innerService.ClientCertificates;
371 | set => _innerService.ClientCertificates = value;
372 | }
373 |
374 | public IWebProxy Proxy
375 | {
376 | get => _innerService.Proxy;
377 | set => _innerService.Proxy = value;
378 | }
379 |
380 | public RequestCachePolicy CachePolicy
381 | {
382 | get => _innerService.CachePolicy;
383 | set => _innerService.CachePolicy = value;
384 | }
385 |
386 | public bool Pipelined
387 | {
388 | get => _innerService.Pipelined;
389 | set => _innerService.Pipelined = value;
390 | }
391 |
392 | public bool FollowRedirects
393 | {
394 | get => _innerService.FollowRedirects;
395 | set => _innerService.FollowRedirects = value;
396 | }
397 |
398 | public RemoteCertificateValidationCallback RemoteCertificateValidationCallback
399 | {
400 | get => _innerService.RemoteCertificateValidationCallback;
401 | set => _innerService.RemoteCertificateValidationCallback = value;
402 | }
403 |
404 | #region Obsolete Methods
405 |
406 | [Obsolete]
407 | public void AddHandler(string contentType, IDeserializer deserializer)
408 | {
409 | _innerService.AddHandler(contentType, deserializer);
410 | }
411 |
412 | [Obsolete]
413 | public byte[] DownloadData(IRestRequest request, bool throwOnError)
414 | {
415 | return _innerService.DownloadData(request, throwOnError);
416 | }
417 |
418 | [Obsolete]
419 | public IRestClient UseSerializer(IRestSerializer serializer)
420 | {
421 | return _innerService.UseSerializer(serializer);
422 | }
423 |
424 | [Obsolete]
425 | public RestRequestAsyncHandle ExecuteAsync(IRestRequest request, Action callback)
426 | {
427 | return _innerService.ExecuteAsync(request, callback);
428 | }
429 |
430 | [Obsolete]
431 | public RestRequestAsyncHandle ExecuteAsync(IRestRequest request, Action, RestRequestAsyncHandle> callback)
432 | {
433 | return _innerService.ExecuteAsync(request, callback);
434 | }
435 |
436 | [Obsolete]
437 | public RestRequestAsyncHandle ExecuteAsync(IRestRequest request, Action callback, Method httpMethod)
438 | {
439 | return _innerService.ExecuteAsync(request, callback, httpMethod);
440 | }
441 |
442 | [Obsolete]
443 | public RestRequestAsyncHandle ExecuteAsync(IRestRequest request, Action, RestRequestAsyncHandle> callback, Method httpMethod)
444 | {
445 | return _innerService.ExecuteAsync(request, callback, httpMethod);
446 | }
447 |
448 | [Obsolete]
449 | public RestRequestAsyncHandle ExecuteAsyncGet(IRestRequest request, Action callback, string httpMethod)
450 | {
451 | return _innerService.ExecuteAsyncGet(request, callback, httpMethod);
452 | }
453 |
454 | [Obsolete]
455 | public RestRequestAsyncHandle ExecuteAsyncPost(IRestRequest request, Action callback, string httpMethod)
456 | {
457 | return _innerService.ExecuteAsyncPost(request, callback, httpMethod);
458 | }
459 |
460 | [Obsolete]
461 | public RestRequestAsyncHandle ExecuteAsyncGet(IRestRequest request, Action, RestRequestAsyncHandle> callback, string httpMethod)
462 | {
463 | return _innerService.ExecuteAsyncGet(request, callback, httpMethod);
464 | }
465 |
466 | [Obsolete]
467 | public RestRequestAsyncHandle ExecuteAsyncPost(IRestRequest request, Action, RestRequestAsyncHandle> callback, string httpMethod)
468 | {
469 | return _innerService.ExecuteAsyncPost(request, callback, httpMethod);
470 | }
471 |
472 | [Obsolete]
473 | public async Task> ExecuteTaskAsync(IRestRequest request)
474 | {
475 | if (null == request)
476 | return null;
477 |
478 | if (null == _pollyRetAsyncPolicy)
479 | return null;
480 |
481 | return await _pollyRetAsyncPolicy.ExecuteAsync(async () => await _innerService.ExecuteTaskAsync(request));
482 | }
483 |
484 | [Obsolete]
485 | public async Task> ExecuteTaskAsync(IRestRequest request, CancellationToken token)
486 | {
487 | if (null == request)
488 | return null;
489 |
490 | if (null == _pollyRetAsyncPolicy)
491 | return null;
492 |
493 | return await _pollyRetAsyncPolicy.ExecuteAsync(async () => await _innerService.ExecuteTaskAsync(request, token));
494 | }
495 |
496 | [Obsolete]
497 | public async Task> ExecuteTaskAsync(IRestRequest request, Method httpMethod)
498 | {
499 | if (null == request)
500 | return null;
501 |
502 | if (null == _pollyRetAsyncPolicy)
503 | return null;
504 |
505 | return await _pollyRetAsyncPolicy.ExecuteAsync(async () => await _innerService.ExecuteTaskAsync(request, httpMethod));
506 | }
507 |
508 | [Obsolete]
509 | public async Task> ExecuteGetTaskAsync(IRestRequest request)
510 | {
511 | if (null == request)
512 | return null;
513 |
514 | if (null == _pollyRetAsyncPolicy)
515 | return null;
516 |
517 | return await _pollyRetAsyncPolicy.ExecuteAsync(async () => await _innerService.ExecuteGetTaskAsync(request));
518 | }
519 |
520 | [Obsolete]
521 | public async Task> ExecuteGetTaskAsync(IRestRequest request, CancellationToken token)
522 | {
523 | if (null == request)
524 | return null;
525 |
526 | if (null == _pollyRetAsyncPolicy)
527 | return null;
528 |
529 | return await _pollyRetAsyncPolicy.ExecuteAsync(async () => await _innerService.ExecuteGetTaskAsync(request, token));
530 | }
531 |
532 | [Obsolete]
533 | public async Task> ExecutePostTaskAsync(IRestRequest request)
534 | {
535 | if (null == request)
536 | return null;
537 |
538 | if (null == _pollyRetAsyncPolicy)
539 | return null;
540 |
541 | return await _pollyRetAsyncPolicy.ExecuteAsync(async () => await _innerService.ExecuteGetTaskAsync(request));
542 | }
543 |
544 | [Obsolete]
545 | public async Task> ExecutePostTaskAsync(IRestRequest request, CancellationToken token)
546 | {
547 | if (null == request)
548 | return null;
549 |
550 | if (null == _pollyRetAsyncPolicy)
551 | return null;
552 |
553 | return await _pollyRetAsyncPolicy.ExecuteAsync(async () => await _innerService.ExecutePostTaskAsync(request, token));
554 | }
555 |
556 | [Obsolete]
557 | public async Task ExecuteTaskAsync(IRestRequest request, CancellationToken token)
558 | {
559 | if (null == request)
560 | return null;
561 |
562 | if (null == _pollyRetAsyncPolicy)
563 | return null;
564 |
565 | return await _pollyRetAsyncPolicy.ExecuteAsync(async () => await _innerService.ExecuteTaskAsync(request, token));
566 | }
567 |
568 | [Obsolete]
569 | public async Task ExecuteTaskAsync(IRestRequest request, CancellationToken token, Method httpMethod)
570 | {
571 | if (null == request)
572 | return null;
573 |
574 | if (null == _pollyRetAsyncPolicy)
575 | return null;
576 |
577 | return await _pollyRetAsyncPolicy.ExecuteAsync(async () => await _innerService.ExecuteTaskAsync(request, token, httpMethod));
578 | }
579 |
580 | [Obsolete]
581 | public async Task ExecuteTaskAsync(IRestRequest request)
582 | {
583 | if (null == request)
584 | return null;
585 |
586 | if (null == _pollyRetAsyncPolicy)
587 | return null;
588 |
589 | return await _pollyRetAsyncPolicy.ExecuteAsync(async () => await _innerService.ExecuteTaskAsync(request));
590 | }
591 |
592 | [Obsolete]
593 | public async Task ExecuteGetTaskAsync(IRestRequest request)
594 | {
595 | if (null == request)
596 | return null;
597 |
598 | if (null == _pollyRetAsyncPolicy)
599 | return null;
600 |
601 | return await _pollyRetAsyncPolicy.ExecuteAsync(async () => await _innerService.ExecuteGetTaskAsync(request));
602 | }
603 |
604 | [Obsolete]
605 | public async Task ExecuteGetTaskAsync(IRestRequest request, CancellationToken token)
606 | {
607 | if (null == request)
608 | return null;
609 |
610 | if (null == _pollyRetAsyncPolicy)
611 | return null;
612 |
613 | return await _pollyRetAsyncPolicy.ExecuteAsync(async () => await _innerService.ExecuteGetTaskAsync(request, token));
614 | }
615 |
616 | [Obsolete]
617 | public async Task ExecutePostTaskAsync(IRestRequest request)
618 | {
619 | if (null == request)
620 | return null;
621 |
622 | if (null == _pollyRetAsyncPolicy)
623 | return null;
624 |
625 | return await _pollyRetAsyncPolicy.ExecuteAsync(async () => await _innerService.ExecutePostTaskAsync(request));
626 | }
627 |
628 | [Obsolete]
629 | public async Task ExecutePostTaskAsync(IRestRequest request, CancellationToken token)
630 | {
631 | if (null == request)
632 | return null;
633 |
634 | if (null == _pollyRetAsyncPolicy)
635 | return null;
636 |
637 | return await _pollyRetAsyncPolicy.ExecuteAsync(async () => await _innerService.ExecutePostTaskAsync(request, token));
638 | }
639 |
640 | #endregion
641 |
642 | }
643 | }
--------------------------------------------------------------------------------
/RestSharpPolly/RestClientFactoryGeneric.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Net;
4 | using System.Net.Cache;
5 | using System.Net.Security;
6 | using System.Security.Cryptography.X509Certificates;
7 | using System.Text;
8 | using System.Threading;
9 | using System.Threading.Tasks;
10 | using Polly;
11 | using RestSharp;
12 | using RestSharp.Authenticators;
13 | using RestSharp.Deserializers;
14 | using RestSharp.Serialization;
15 |
16 | namespace RestSharpPolly
17 | {
18 | ///
19 | /// A REST client factory.
20 | ///
21 | public class RestClientFactory : RestClientBase, IRestClient where TResult : IRestResponse
22 | {
23 | private static readonly Lazy> LazyRestFac = new Lazy>(() => new RestClientFactory());
24 | private static readonly Lazy LazyRestClient = new Lazy(() => new RestClient());
25 | private ISyncPolicy _pollyRetPolicyGeneric;
26 | private IAsyncPolicy _pollyRetAsyncPolicyGeneric;
27 | private static RestClientFactory InstanceRestClient => LazyRestFac.Value;
28 | private static IRestClient _innerService => LazyRestClient.Value;
29 |
30 |
31 | private RestClientFactory() : base(_innerService)
32 | {
33 | }
34 |
35 | public static IRestClient Create()
36 | {
37 | return _innerService;
38 | }
39 |
40 | public static RestClientFactory Create(ISyncPolicy syncPolicy)
41 | {
42 | return InstanceRestClient.SetPolicy(syncPolicy);
43 | }
44 |
45 | public static RestClientFactory Create(IAsyncPolicy asyncPolicy)
46 | {
47 | return InstanceRestClient.SetAsyncPolicy(asyncPolicy);
48 | }
49 | public static RestClientFactory Create(IAsyncPolicy asyncPolicy)
50 | {
51 | return InstanceRestClient.SetAsyncPolicy(asyncPolicy);
52 | }
53 |
54 | public RestClientFactory SetAsyncPolicy(IAsyncPolicy asyncPolicyGeneric)
55 | {
56 | _pollyRetAsyncPolicyGeneric = (IAsyncPolicy)asyncPolicyGeneric;
57 | return InstanceRestClient;
58 | }
59 | public RestClientFactory SetAsyncPolicy(IAsyncPolicy asyncPolicyGeneric)
60 | {
61 | _pollyRetAsyncPolicyGeneric = (IAsyncPolicy)asyncPolicyGeneric;
62 | return InstanceRestClient;
63 | }
64 | public RestClientFactory SetPolicy(ISyncPolicy syncPolicyGeneric)
65 | {
66 | _pollyRetPolicyGeneric = (ISyncPolicy)syncPolicyGeneric;
67 | return InstanceRestClient;
68 | }
69 |
70 | public IRestClient UseSerializer(Func serializerFactory)
71 | {
72 | return _innerService.UseSerializer(serializerFactory);
73 | }
74 |
75 | public IRestClient UseSerializer() where T : IRestSerializer, new()
76 | {
77 | return _innerService.UseSerializer();
78 | }
79 |
80 | public IRestResponse Deserialize(IRestResponse response)
81 | {
82 | return _innerService.Deserialize(response);
83 | }
84 |
85 | public IRestClient UseUrlEncoder(Func encoder)
86 | {
87 | return _innerService.UseUrlEncoder(encoder);
88 | }
89 |
90 | public IRestClient UseQueryEncoder(Func queryEncoder)
91 | {
92 | return _innerService.UseQueryEncoder(queryEncoder);
93 | }
94 |
95 | public IRestResponse Execute(IRestRequest request)
96 | {
97 | if (null == request)
98 | throw new AggregateException(nameof(request) + " is null");
99 | return ExecutePolly(x => x.Execute(request), request, _pollyRetPolicyGeneric);
100 |
101 | }
102 |
103 | public IRestResponse Execute(IRestRequest request, Method httpMethod)
104 | {
105 | if (null == request)
106 | throw new AggregateException(nameof(request) + " is null");
107 | return ExecutePolly(x => x.Execute(request, httpMethod), request, _pollyRetPolicyGeneric);
108 |
109 | }
110 |
111 | public IRestResponse Execute(IRestRequest request)
112 | {
113 | if (null == request)
114 | throw new AggregateException(nameof(request) + " is null");
115 | return ExecutePollyT(x => x.Execute(request), request, _pollyRetPolicyGeneric as ISyncPolicy);
116 |
117 | }
118 |
119 | public IRestResponse Execute(IRestRequest request, Method httpMethod)
120 | {
121 | if (null == request)
122 | throw new AggregateException(nameof(request) + " is null");
123 | return ExecutePollyT(x => x.Execute(request, httpMethod), request, _pollyRetPolicyGeneric as ISyncPolicy);
124 |
125 | }
126 |
127 | public byte[] DownloadData(IRestRequest request)
128 | {
129 | return _innerService.DownloadData(request);
130 | }
131 |
132 | public Uri BuildUri(IRestRequest request)
133 | {
134 | return _innerService.BuildUri(request);
135 | }
136 |
137 | public string BuildUriWithoutQueryParameters(IRestRequest request)
138 | {
139 | return _innerService.BuildUriWithoutQueryParameters(request);
140 | }
141 |
142 | public void ConfigureWebRequest(Action configurator)
143 | {
144 | _innerService.ConfigureWebRequest(configurator);
145 | }
146 |
147 | public void AddHandler(string contentType, Func deserializerFactory)
148 | {
149 | _innerService.AddHandler(contentType, deserializerFactory);
150 | }
151 |
152 | public void RemoveHandler(string contentType)
153 | {
154 | _innerService.RemoveHandler(contentType);
155 | }
156 |
157 | public void ClearHandlers()
158 | {
159 | _innerService.ClearHandlers();
160 | }
161 |
162 | public IRestResponse ExecuteAsGet(IRestRequest request, string httpMethod)
163 | {
164 | if (null == request)
165 | throw new AggregateException(nameof(request) + " is null");
166 | return ExecutePolly(x => x.ExecuteAsGet(request, httpMethod), request, _pollyRetPolicyGeneric);
167 |
168 | }
169 |
170 | public IRestResponse ExecuteAsPost(IRestRequest request, string httpMethod)
171 | {
172 | if (null == request)
173 | throw new AggregateException(nameof(request) + " is null");
174 | return ExecutePolly(x => x.ExecuteAsPost(request, httpMethod), request, _pollyRetPolicyGeneric);
175 |
176 | }
177 |
178 | public IRestResponse ExecuteAsGet(IRestRequest request, string httpMethod)
179 | {
180 | if (null == request)
181 | throw new AggregateException(nameof(request) + " is null");
182 | return ExecutePollyT(x => x.ExecuteAsGet(request, httpMethod), request, _pollyRetPolicyGeneric as ISyncPolicy);
183 |
184 | }
185 |
186 | public IRestResponse ExecuteAsPost(IRestRequest request, string httpMethod)
187 | {
188 | if (null == request)
189 | throw new AggregateException(nameof(request) + " is null");
190 | return ExecutePollyT(x => x.ExecuteAsPost(request, httpMethod), request, _pollyRetPolicyGeneric as ISyncPolicy