diff --git a/DragonFruit.Data/ApiClient.cs b/DragonFruit.Data/ApiClient.cs index e103e9f..f03a6eb 100644 --- a/DragonFruit.Data/ApiClient.cs +++ b/DragonFruit.Data/ApiClient.cs @@ -22,7 +22,18 @@ namespace DragonFruit.Data /// Represents a strongly-typed serializer version of /// /// The type of the - public class ApiClient() : ApiClient(Activator.CreateInstance()) where T : ApiSerializer, new(); + public class ApiClient : ApiClient where T : ApiSerializer, new() + { + public ApiClient() + : base(new T()) + { + } + + public ApiClient(Uri baseAddress) + : base(new T(), baseAddress) + { + } + } /// /// The responsible for building, submitting and processing HTTP requests @@ -30,12 +41,19 @@ namespace DragonFruit.Data public class ApiClient { private HttpClient _client; + private Uri _baseAddress; public ApiClient(ApiSerializer serializer) { Serializers = new SerializerResolver(serializer); } + public ApiClient(ApiSerializer serializer, Uri baseAddress) + : this(serializer) + { + _baseAddress = baseAddress; + } + ~ApiClient() { _client?.Dispose(); @@ -69,6 +87,23 @@ public string UserAgent } } + /// + /// Gets or sets the that should act as the base address for relative-URI requests + /// + public Uri BaseAddress + { + get => _client?.BaseAddress ?? _baseAddress; + set + { + _baseAddress = value; + + if (_client != null) + { + _client.BaseAddress = value; + } + } + } + /// /// The instance used to resolve serializers for requests. /// Caches and reused serializers where possible. @@ -327,6 +362,7 @@ protected virtual HttpClient CreateClient() client.DefaultVersionPolicy = HttpVersionPolicy.RequestVersionOrHigher; #endif + client.BaseAddress = _baseAddress; return client; } @@ -362,40 +398,41 @@ protected virtual async Task ValidateAndProcess(HttpResponseMessage respon /// The to send protected virtual async ValueTask BuildRequest(ApiRequest request, string expectedContentType) { - if (request is IRequestExecutingCallback callback) + switch (request) { - callback.OnRequestExecuting(this); - } + case IRequestExecutingCallback callback: + callback.OnRequestExecuting(this); + break; - if (request is IAsyncRequestExecutingCallback asyncCallback) - { - await asyncCallback.OnRequestExecuting(this); + case IAsyncRequestExecutingCallback asyncCallback: + await asyncCallback.OnRequestExecuting(this); + break; } - var requestMessage = request is IRequestBuilder rb - ? rb.BuildRequest(Serializers) - : ReflectionRequestMessageBuilder.CreateHttpRequestMessage(request, Serializers); - + var requestMessage = (request as IRequestBuilder)?.BuildRequest(Serializers) ?? ReflectionRequestMessageBuilder.CreateHttpRequestMessage(request, Serializers); requestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(expectedContentType)); + return requestMessage; } public static HttpMessageHandler CreateDefaultHandler() { -#if NETSTANDARD2_0 +#if !NETSTANDARD2_0 + if (SocketsHttpHandler.IsSupported) + { + return new SocketsHttpHandler + { + UseCookies = false, + AutomaticDecompression = DecompressionMethods.All, + PooledConnectionLifetime = TimeSpan.FromMinutes(10) + }; + } +#endif return new HttpClientHandler { UseCookies = false, AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip }; -#else - return new SocketsHttpHandler - { - UseCookies = false, - AutomaticDecompression = DecompressionMethods.All, - PooledConnectionLifetime = TimeSpan.FromMinutes(10) - }; -#endif } } }