11using Newtonsoft . Json ;
2+ using Rubberduck . Settings ;
23using System ;
34using System . Net ;
45using System . Net . Http ;
910
1011namespace Rubberduck . Client . Abstract
1112{
12- public abstract class ApiClientBase : IDisposable
13+ public interface IHttpClientProvider
14+ {
15+ HttpClient GetClient ( ) ;
16+ }
17+
18+ public sealed class HttpClientProvider : IHttpClientProvider , IDisposable
19+ {
20+ private readonly Lazy < HttpClient > _client ;
21+
22+ public HttpClientProvider ( Func < HttpClient > getClient )
23+ {
24+ _client = new Lazy < HttpClient > ( getClient ) ;
25+ }
26+
27+ public HttpClient GetClient ( )
28+ {
29+ return _client . Value ;
30+ }
31+
32+ public void Dispose ( )
33+ {
34+ if ( _client . IsValueCreated )
35+ {
36+ _client . Value . Dispose ( ) ;
37+ }
38+ }
39+ }
40+
41+ public abstract class ApiClientBase
1342 {
1443 protected static readonly string UserAgentName = "Rubberduck" ;
15- protected static readonly string BaseUrl = "https://api.rubberduckvba.com/api/v1/" ;
1644 protected static readonly string ContentTypeApplicationJson = "application/json" ;
1745 protected static readonly int MaxAttempts = 3 ;
1846 protected static readonly TimeSpan RetryCooldownDelay = TimeSpan . FromSeconds ( 1 ) ;
1947
20- protected readonly Lazy < HttpClient > _client ;
48+ protected readonly IHttpClientProvider _clientProvider ;
49+ protected readonly string _baseUrl ;
2150
22- protected ApiClientBase ( )
51+ protected ApiClientBase ( IGeneralSettings settings , IHttpClientProvider clientProvider )
2352 {
24- _client = new Lazy < HttpClient > ( ( ) => GetClient ( ) ) ;
53+ _clientProvider = clientProvider ;
54+ _baseUrl = string . IsNullOrWhiteSpace ( settings . ApiBaseUrl ) ? "https://api.rubberduckvba.com/api/v1/" : settings . ApiBaseUrl ;
2555 }
2656
2757 protected HttpClient GetClient ( )
2858 {
2959 ServicePointManager . SecurityProtocol = SecurityProtocolType . Tls12 ;
30- var client = new HttpClient ( ) ;
31- return ConfigureClient ( client ) ;
60+ var client = _clientProvider . GetClient ( ) ;
61+ ConfigureClient ( client ) ;
62+ return client ;
3263 }
3364
34- protected virtual HttpClient ConfigureClient ( HttpClient client )
65+ protected virtual void ConfigureClient ( HttpClient client )
3566 {
3667 var userAgentVersion = System . Reflection . Assembly . GetExecutingAssembly ( ) . GetName ( ) . Version . ToString ( 3 ) ;
3768 var userAgentHeader = new ProductInfoHeaderValue ( UserAgentName , userAgentVersion ) ;
3869
3970 client . DefaultRequestHeaders . UserAgent . Add ( userAgentHeader ) ;
40- return client ;
4171 }
4272
4373 protected virtual async Task < TResult > GetResponse < TResult > ( string route , CancellationToken ? cancellationToken = null )
4474 {
45- var uri = new Uri ( $ "{ BaseUrl } { route } ") ;
75+ var uri = new Uri ( $ "{ _baseUrl } { route } ") ;
4676
4777 var attempt = 0 ;
4878 var token = cancellationToken ?? CancellationToken . None ;
@@ -102,7 +132,7 @@ protected virtual async Task<TResult> GetResponse<TResult>(string route, Cancell
102132
103133 protected virtual async Task < TResult > Post < TArgs , TResult > ( string route , TArgs args , CancellationToken ? cancellationToken = null )
104134 {
105- var uri = new Uri ( $ "{ BaseUrl } { route } ") ;
135+ var uri = new Uri ( $ "{ _baseUrl } { route } ") ;
106136 string json ;
107137 try
108138 {
@@ -167,13 +197,5 @@ protected virtual async Task<TResult> Post<TArgs, TResult>(string route, TArgs a
167197 return default ;
168198 }
169199 }
170-
171- public void Dispose ( )
172- {
173- if ( _client . IsValueCreated )
174- {
175- _client . Value . Dispose ( ) ;
176- }
177- }
178200 }
179201}
0 commit comments