using CryptoExchange.Net.Objects; using System; using System.Collections.Generic; using System.Data.Common; using System.Linq; namespace CryptoExchange.Net.SharedApis { /// /// Exchange parameters /// public class ExchangeParameters { private readonly static Dictionary _staticProcessParameters = new Dictionary(); private readonly Dictionary _processParameters; /// /// Create a new ExchangeParameters instance with the provided parameters set /// /// Exchange parameters public ExchangeParameters(params ExchangeParameter[] parameters) { _processParameters = new Dictionary(); foreach (var parameter in parameters) AddValue(parameter.Exchange, parameter.Name, parameter.Value); } /// /// Add a process parameter. Process parameters are used to determine the correct logic to execute, but are not necessarily passed to the API.
/// To directly add or override parameters which are passed to the API, use AddRawParameter or AddRawValue instead. ///
/// The exchange parameter to add public void AddValue(ExchangeParameter exchangeParameter) { AddValue(exchangeParameter.Exchange, exchangeParameter.Name, exchangeParameter.Value); } /// /// Add a process parameter. Process parameters are used to determine the correct logic to execute, but are not necessarily passed to the API.
/// To directly add or override parameters which are passed to the API, use AddRawParameter or AddRawValue instead. ///
/// Exchange to apply the parameter for /// Parameter name /// Parameter value public void AddValue(string exchange, string key, object value) { if (!_processParameters.TryGetValue(exchange, out var exchangeParameters)) { exchangeParameters = new Parameters(ParameterSerializationSettings.Default); _processParameters[exchange] = exchangeParameters; } exchangeParameters.AddRaw(key, value); } /// /// Check whether a specific parameter is provided in this specific instance /// /// The exchange name /// Parameter name /// Type of the parameter value /// public bool HasValue(string exchange, string name, Type type) { var val = TryGetValue(_processParameters, exchange, name); val ??= TryGetValue(_staticProcessParameters, exchange, name); if (val == null) return false; try { Type t = Nullable.GetUnderlyingType(type) ?? type; Convert.ChangeType(val, t); return true; } catch { return false; } } /// /// Check whether a specific process parameter is provided in the default parameters or the provided instance /// /// The provided exchange parameter in the request /// The exchange name /// Parameter name /// Type of the parameter value /// public static bool HasValue(ExchangeParameters? exchangeParameters, string exchange, string name, Type type) { var provided = exchangeParameters?.HasValue(exchange, name, type); if (provided == true) return true; var val = TryGetValue(_staticProcessParameters, exchange, name); if (val == null) return false; try { Type t = Nullable.GetUnderlyingType(type) ?? type; Convert.ChangeType(val, t); return true; } catch { return false; } } /// /// Get the value of a parameter from this instance /// /// Type of the parameter value /// Exchange name /// Parameter name public T? GetValue(string exchange, string name) { var val = TryGetValue(_processParameters, exchange, name); val ??= TryGetValue(_staticProcessParameters, exchange, name); if (val == null) return default; if (val is T typeVal) return typeVal; try { Type t = Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T); return (T)Convert.ChangeType(val, t); } catch { throw new ArgumentException("Incorrect type for parameter, expected " + typeof(T).Name, name); } } /// /// Get the value of a parameter from this instance or the default values /// /// Type of the parameter value /// The request parameters /// Exchange name /// Parameter name public static T? GetValue(ExchangeParameters? exchangeParameters, string exchange, string name) { if (exchangeParameters != null) { var provided = exchangeParameters.GetValue(exchange, name); if (provided != null) return provided; } var val = TryGetValue(_staticProcessParameters, exchange, name); if (val == null) return default; try { var type = typeof(T); Type t = Nullable.GetUnderlyingType(type) ?? type; var result = Convert.ChangeType(val, t); return (T)result; } catch { throw new ArgumentException("Incorrect type for parameter, expected " + typeof(T).Name, name); } } /// /// Set static parameters /// /// Exchange name /// Parameter name /// Parameter value public static void SetStaticParameter(string exchange, string key, object value) { if (!_staticProcessParameters.TryGetValue(exchange, out var exchangeParameters)) { exchangeParameters = new Parameters(ParameterSerializationSettings.Default); _staticProcessParameters[exchange] = exchangeParameters; } exchangeParameters.Remove(key); exchangeParameters.AddRaw(key, value); } /// /// Reset the static parameters, clears all parameters for all exchanges /// public static void ResetStaticParameters() { _staticProcessParameters.Clear(); } /// /// Reset the static parameters, clears all parameters for an exchange exchanges /// public static void ResetStaticExchangeParameters(string exchange) { _staticProcessParameters.Remove(exchange); } private static object? TryGetValue(Dictionary list, string exchange, string key) { if (!list.TryGetValue(exchange, out var exchangeParams)) return null; return exchangeParams.SingleOrDefault(x => x.Key.Equals(key, StringComparison.InvariantCultureIgnoreCase)).Value; } } }