diff --git a/CryptoExchange.Net/Clients/BaseApiClient.cs b/CryptoExchange.Net/Clients/BaseApiClient.cs index 80377dd..7029d83 100644 --- a/CryptoExchange.Net/Clients/BaseApiClient.cs +++ b/CryptoExchange.Net/Clients/BaseApiClient.cs @@ -1,20 +1,6 @@ using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.IO; -using System.Linq; -using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; -using System.Web; using CryptoExchange.Net.Authentication; -using CryptoExchange.Net.Interfaces; using CryptoExchange.Net.Objects; -using CryptoExchange.Net.Requests; -using Microsoft.Extensions.Logging; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; namespace CryptoExchange.Net { @@ -23,7 +9,7 @@ namespace CryptoExchange.Net /// public abstract class BaseApiClient: IDisposable { - private readonly ApiCredentials? _apiCredentials; + private ApiCredentials? _apiCredentials; private AuthenticationProvider? _authenticationProvider; private bool _created; @@ -67,6 +53,14 @@ namespace CryptoExchange.Net /// protected abstract AuthenticationProvider CreateAuthenticationProvider(ApiCredentials credentials); + /// + public void SetApiCredentials(ApiCredentials credentials) + { + _apiCredentials = credentials; + _created = false; + _authenticationProvider = null; + } + /// /// Dispose /// diff --git a/CryptoExchange.Net/Clients/BaseClient.cs b/CryptoExchange.Net/Clients/BaseClient.cs index e923596..713efa3 100644 --- a/CryptoExchange.Net/Clients/BaseClient.cs +++ b/CryptoExchange.Net/Clients/BaseClient.cs @@ -5,6 +5,7 @@ using Microsoft.Extensions.Logging; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; +using System.Collections.Generic; using System.Globalization; using System.IO; using System.Text; @@ -22,6 +23,10 @@ namespace CryptoExchange.Net /// internal string ExchangeName { get; } /// + /// Api clients in this client + /// + internal List ApiClients { get; } = new List(); + /// /// The log object /// protected internal Log log; @@ -66,6 +71,16 @@ namespace CryptoExchange.Net log.Write(LogLevel.Debug, $"Client configuration: {options}, CryptoExchange.Net: v{typeof(BaseClient).Assembly.GetName().Version}, {ExchangeName}.Net: v{GetType().Assembly.GetName().Version}"); } + /// + /// Register an API client + /// + /// The client + protected T AddApiClient(T apiClient) where T: BaseApiClient + { + ApiClients.Add(apiClient); + return apiClient; + } + /// /// Tries to parse the json data and return a JToken, validating the input not being empty and being valid json /// @@ -263,6 +278,8 @@ namespace CryptoExchange.Net public virtual void Dispose() { log.Write(LogLevel.Debug, "Disposing exchange client"); + foreach (var client in ApiClients) + client.Dispose(); } } } diff --git a/CryptoExchange.Net/Clients/BaseRestClient.cs b/CryptoExchange.Net/Clients/BaseRestClient.cs index 1d21c3a..a2df127 100644 --- a/CryptoExchange.Net/Clients/BaseRestClient.cs +++ b/CryptoExchange.Net/Clients/BaseRestClient.cs @@ -7,7 +7,7 @@ using System.Linq; using System.Net.Http; using System.Threading; using System.Threading.Tasks; -using System.Web; +using CryptoExchange.Net.Authentication; using CryptoExchange.Net.Interfaces; using CryptoExchange.Net.Objects; using CryptoExchange.Net.Requests; @@ -57,9 +57,9 @@ namespace CryptoExchange.Net /// What request body should be set when no data is send (only used in combination with postParametersPosition.InBody) /// protected string requestBodyEmptyContent = "{}"; - + /// - public int TotalRequestsMade { get; private set; } + public int TotalRequestsMade => ApiClients.OfType().Sum(s => s.TotalRequestsMade); /// /// Request headers to be sent with each request @@ -85,6 +85,12 @@ namespace CryptoExchange.Net RequestFactory.Configure(exchangeOptions.RequestTimeout, exchangeOptions.Proxy, exchangeOptions.HttpClient); } + /// + public void SetApiCredentials(ApiCredentials credentials) + { + foreach (var apiClient in ApiClients) + apiClient.SetApiCredentials(credentials); + } /// /// Execute a request to the uri and deserialize the response into the provided type parameter @@ -154,8 +160,6 @@ namespace CryptoExchange.Net } apiClient.TotalRequestsMade++; - TotalRequestsMade++; - log.Write(LogLevel.Debug, $"[{requestId}] Sending {method}{(signed ? " signed" : "")} request to {request.Uri}{paramString ?? " "}{(ClientOptions.Proxy == null ? "" : $" via proxy {ClientOptions.Proxy.Host}")}"); return await GetResponseAsync(request, deserializer, cancellationToken).ConfigureAwait(false); } @@ -352,48 +356,6 @@ namespace CryptoExchange.Net } return request; - - //var uriString = uri.ToString(); - //if (apiClient.AuthenticationProvider != null) - // parameters = apiClient.AuthenticationProvider.AddAuthenticationToParameters(uriString, method, parameters, signed, parameterPosition, arraySerialization); - - //if (parameterPosition == HttpMethodParameterPosition.InUri && parameters?.Any() == true) - // uriString += "?" + parameters.CreateParamString(true, arraySerialization); - - //var contentType = requestBodyFormat == RequestBodyFormat.Json ? Constants.JsonContentHeader : Constants.FormContentHeader; - //var request = RequestFactory.Create(method, uriString, requestId); - //request.Accept = Constants.JsonContentHeader; - - //var headers = new Dictionary(); - //if (apiClient.AuthenticationProvider != null) - // headers = apiClient.AuthenticationProvider.AddAuthenticationToHeaders(uriString, method, parameters!, signed, parameterPosition, arraySerialization); - - //foreach (var header in headers) - // request.AddHeader(header.Key, header.Value); - - //if (additionalHeaders != null) - //{ - // foreach (var header in additionalHeaders) - // request.AddHeader(header.Key, header.Value); - //} - - //if(StandardRequestHeaders != null) - //{ - // foreach (var header in StandardRequestHeaders) - // // Only add it if it isn't overwritten - // if(additionalHeaders?.ContainsKey(header.Key) != true) - // request.AddHeader(header.Key, header.Value); - //} - - //if (parameterPosition == HttpMethodParameterPosition.InBody) - //{ - // if (parameters?.Any() == true) - // WriteParamBody(request, parameters, contentType); - // else - // request.SetContent(requestBodyEmptyContent, contentType); - //} - - //return request; } /// @@ -427,11 +389,5 @@ namespace CryptoExchange.Net { return new ServerError(error.ToString()); } - - /// - public override void Dispose() - { - base.Dispose(); - } } } diff --git a/CryptoExchange.Net/Interfaces/IRestClient.cs b/CryptoExchange.Net/Interfaces/IRestClient.cs index 1eabc49..30e9604 100644 --- a/CryptoExchange.Net/Interfaces/IRestClient.cs +++ b/CryptoExchange.Net/Interfaces/IRestClient.cs @@ -1,4 +1,5 @@ using System; +using CryptoExchange.Net.Authentication; using CryptoExchange.Net.Objects; namespace CryptoExchange.Net.Interfaces @@ -22,5 +23,11 @@ namespace CryptoExchange.Net.Interfaces /// The options provided for this client /// BaseRestClientOptions ClientOptions { get; } + + /// + /// Set the API credentials for this client. All Api clients in this client will use the new credentials, regardless of earlier set options. + /// + /// The credentials to set + void SetApiCredentials(ApiCredentials credentials); } } \ No newline at end of file