Skip to content

Commit 7d4ba15

Browse files
authored
Client Configuration (#59)
Updated CryptoExchange.Net to version 8.3.0 Added support for loading client settings from IConfiguration Added DI registration method for configuring Rest and Socket options at the same time Added DisplayName and ImageUrl properties to OKXExchange class Updated client constructors to accept IOptions from DI Removed redundant OKXSocketClient constructor
1 parent ff40aa4 commit 7d4ba15

16 files changed

+419
-103
lines changed

Diff for: OKX.Net.UnitTests/OKXRestIntegrationTests.cs

+6-4
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
using System.Linq;
1010
using System.Text;
1111
using System.Threading.Tasks;
12+
using Microsoft.Extensions.Options;
13+
using OKX.Net.Objects.Options;
1214

1315
namespace OKX.Net.UnitTests
1416
{
@@ -28,11 +30,11 @@ public override OKXRestClient GetClient(ILoggerFactory loggerFactory)
2830
var pass = Environment.GetEnvironmentVariable("APIPASS");
2931

3032
Authenticated = key != null && sec != null;
31-
return new OKXRestClient(null, loggerFactory, opts =>
33+
return new OKXRestClient(null, loggerFactory, Options.Create(new OKXRestOptions
3234
{
33-
opts.OutputOriginalData = true;
34-
opts.ApiCredentials = Authenticated ? new OKXApiCredentials(key, sec, pass) : null;
35-
});
35+
OutputOriginalData = true,
36+
ApiCredentials = Authenticated ? new OKXApiCredentials(key, sec, pass) : null
37+
}));
3638
}
3739

3840
[Test]

Diff for: OKX.Net.UnitTests/OXKRestClientTests.cs

+106
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
using CryptoExchange.Net.Clients;
66
using OKX.Net.Objects;
77
using System.Text.Json;
8+
using Microsoft.Extensions.Configuration;
9+
using Microsoft.Extensions.DependencyInjection;
10+
using CryptoExchange.Net.Objects;
11+
using OKX.Net.Interfaces.Clients;
812

913
namespace OKX.Net.UnitTests
1014
{
@@ -101,5 +105,107 @@ public void CheckInterfaces()
101105
CryptoExchange.Net.Testing.TestHelpers.CheckForMissingRestInterfaces<OKXRestClient>();
102106
CryptoExchange.Net.Testing.TestHelpers.CheckForMissingSocketInterfaces<OKXSocketClient>();
103107
}
108+
109+
110+
[Test]
111+
[TestCase(TradeEnvironmentNames.Live, "https://www.okx.com")]
112+
[TestCase(TradeEnvironmentNames.Testnet, "https://www.okx.com")]
113+
[TestCase("", "https://www.okx.com")]
114+
public void TestConstructorEnvironments(string environmentName, string expected)
115+
{
116+
var configuration = new ConfigurationBuilder()
117+
.AddInMemoryCollection(new Dictionary<string, string>
118+
{
119+
{ "OKX:Environment:Name", environmentName },
120+
}).Build();
121+
122+
var collection = new ServiceCollection();
123+
collection.AddOKX(configuration.GetSection("OKX"));
124+
var provider = collection.BuildServiceProvider();
125+
126+
var client = provider.GetRequiredService<IOKXRestClient>();
127+
128+
var address = client.UnifiedApi.BaseAddress;
129+
130+
Assert.That(address, Is.EqualTo(expected));
131+
}
132+
133+
[Test]
134+
public void TestConstructorNullEnvironment()
135+
{
136+
var configuration = new ConfigurationBuilder()
137+
.AddInMemoryCollection(new Dictionary<string, string>
138+
{
139+
{ "OKX", null },
140+
}).Build();
141+
142+
var collection = new ServiceCollection();
143+
collection.AddOKX(configuration.GetSection("OKX"));
144+
var provider = collection.BuildServiceProvider();
145+
146+
var client = provider.GetRequiredService<IOKXRestClient>();
147+
148+
var address = client.UnifiedApi.BaseAddress;
149+
150+
Assert.That(address, Is.EqualTo("https://www.okx.com"));
151+
}
152+
153+
[Test]
154+
public void TestConstructorApiOverwriteEnvironment()
155+
{
156+
var configuration = new ConfigurationBuilder()
157+
.AddInMemoryCollection(new Dictionary<string, string>
158+
{
159+
{ "OKX:Environment:Name", "test" },
160+
{ "OKX:Rest:Environment:Name", "live" },
161+
}).Build();
162+
163+
var collection = new ServiceCollection();
164+
collection.AddOKX(configuration.GetSection("OKX"));
165+
var provider = collection.BuildServiceProvider();
166+
167+
var client = provider.GetRequiredService<IOKXRestClient>();
168+
169+
var address = client.UnifiedApi.BaseAddress;
170+
171+
Assert.That(address, Is.EqualTo("https://www.okx.com"));
172+
}
173+
174+
[Test]
175+
public void TestConstructorConfiguration()
176+
{
177+
var configuration = new ConfigurationBuilder()
178+
.AddInMemoryCollection(new Dictionary<string, string>
179+
{
180+
{ "ApiCredentials:Key", "123" },
181+
{ "ApiCredentials:Secret", "456" },
182+
{ "ApiCredentials:PassPhrase", "222" },
183+
{ "Socket:ApiCredentials:Key", "456" },
184+
{ "Socket:ApiCredentials:Secret", "789" },
185+
{ "Socket:ApiCredentials:PassPhrase", "111" },
186+
{ "Rest:OutputOriginalData", "true" },
187+
{ "Socket:OutputOriginalData", "false" },
188+
{ "Rest:Proxy:Host", "host" },
189+
{ "Rest:Proxy:Port", "80" },
190+
{ "Socket:Proxy:Host", "host2" },
191+
{ "Socket:Proxy:Port", "81" },
192+
}).Build();
193+
194+
var collection = new ServiceCollection();
195+
collection.AddOKX(configuration);
196+
var provider = collection.BuildServiceProvider();
197+
198+
var restClient = provider.GetRequiredService<IOKXRestClient>();
199+
var socketClient = provider.GetRequiredService<IOKXSocketClient>();
200+
201+
Assert.That(((BaseApiClient)restClient.UnifiedApi).OutputOriginalData, Is.True);
202+
Assert.That(((BaseApiClient)socketClient.UnifiedApi).OutputOriginalData, Is.False);
203+
Assert.That(((BaseApiClient)restClient.UnifiedApi).AuthenticationProvider.ApiKey, Is.EqualTo("123"));
204+
Assert.That(((BaseApiClient)socketClient.UnifiedApi).AuthenticationProvider.ApiKey, Is.EqualTo("456"));
205+
Assert.That(((BaseApiClient)restClient.UnifiedApi).ClientOptions.Proxy.Host, Is.EqualTo("host"));
206+
Assert.That(((BaseApiClient)restClient.UnifiedApi).ClientOptions.Proxy.Port, Is.EqualTo(80));
207+
Assert.That(((BaseApiClient)socketClient.UnifiedApi).ClientOptions.Proxy.Host, Is.EqualTo("host2"));
208+
Assert.That(((BaseApiClient)socketClient.UnifiedApi).ClientOptions.Proxy.Port, Is.EqualTo(81));
209+
}
104210
}
105211
}

Diff for: OKX.Net/Clients/OKXRestClient.cs

+8-11
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using CryptoExchange.Net.Clients;
2+
using Microsoft.Extensions.Options;
23
using OKX.Net.Clients.UnifiedApi;
34
using OKX.Net.Interfaces.Clients;
45
using OKX.Net.Interfaces.Clients.UnifiedApi;
@@ -22,25 +23,23 @@ public class OKXRestClient : BaseRestClient, IOKXRestClient
2223
/// Create a new instance of the OKXRestClient using provided options
2324
/// </summary>
2425
/// <param name="optionsDelegate">Option configuration delegate</param>
25-
public OKXRestClient(Action<OKXRestOptions>? optionsDelegate = null) : this(null, null, optionsDelegate)
26+
public OKXRestClient(Action<OKXRestOptions>? optionsDelegate = null)
27+
: this(null, null, Options.Create(ApplyOptionsDelegate(optionsDelegate)))
2628
{
2729
}
2830

2931
/// <summary>
3032
/// Create a new instance of the OKXRestClient
3133
/// </summary>
32-
/// <param name="optionsDelegate">Option configuration delegate</param>
34+
/// <param name="options">Option configuration</param>
3335
/// <param name="loggerFactory">The logger factory</param>
3436
/// <param name="httpClient">Http client for this client</param>
35-
public OKXRestClient(HttpClient? httpClient, ILoggerFactory? loggerFactory, Action<OKXRestOptions>? optionsDelegate = null)
37+
public OKXRestClient(HttpClient? httpClient, ILoggerFactory? loggerFactory, IOptions<OKXRestOptions> options)
3638
: base(loggerFactory, "OKX")
3739
{
38-
var options = OKXRestOptions.Default.Copy();
39-
if (optionsDelegate != null)
40-
optionsDelegate(options);
41-
Initialize(options);
40+
Initialize(options.Value);
4241

43-
UnifiedApi = AddApiClient(new OKXRestClientUnifiedApi(_logger, httpClient, options));
42+
UnifiedApi = AddApiClient(new OKXRestClientUnifiedApi(_logger, httpClient, options.Value));
4443
}
4544
#endregion
4645

@@ -51,9 +50,7 @@ public OKXRestClient(HttpClient? httpClient, ILoggerFactory? loggerFactory, Acti
5150
/// <param name="optionsDelegate">Callback for setting the options</param>
5251
public static void SetDefaultOptions(Action<OKXRestOptions> optionsDelegate)
5352
{
54-
var options = OKXRestOptions.Default.Copy();
55-
optionsDelegate(options);
56-
OKXRestOptions.Default = options;
53+
OKXRestOptions.Default = ApplyOptionsDelegate(optionsDelegate);
5754
}
5855

5956
/// <summary>

Diff for: OKX.Net/Clients/OKXSocketClient.cs

+8-17
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using CryptoExchange.Net.Clients;
2+
using Microsoft.Extensions.Options;
23
using OKX.Net.Clients.UnifiedApi;
34
using OKX.Net.Interfaces.Clients;
45
using OKX.Net.Interfaces.Clients.UnifiedApi;
@@ -16,34 +17,26 @@ public class OKXSocketClient : BaseSocketClient, IOKXSocketClient
1617
public IOKXSocketClientUnifiedApi UnifiedApi { get; }
1718

1819
#region ctor
19-
/// <summary>
20-
/// Create a new instance of the OKXSocketClient
21-
/// </summary>
22-
/// <param name="loggerFactory">The logger</param>
23-
public OKXSocketClient(ILoggerFactory? loggerFactory = null) : this((x) => { }, loggerFactory)
24-
{
25-
}
2620

2721
/// <summary>
2822
/// Create a new instance of the OKXSocketClient
2923
/// </summary>
3024
/// <param name="optionsDelegate">Option configuration delegate</param>
31-
public OKXSocketClient(Action<OKXSocketOptions> optionsDelegate) : this(optionsDelegate, null)
25+
public OKXSocketClient(Action<OKXSocketOptions>? optionsDelegate = null)
26+
: this(Options.Create(ApplyOptionsDelegate(optionsDelegate)), null)
3227
{
3328
}
3429

3530
/// <summary>
3631
/// Create a new instance of the OKXSocketClient
3732
/// </summary>
3833
/// <param name="loggerFactory">The logger</param>
39-
/// <param name="optionsDelegate">Option configuration delegate</param>
40-
public OKXSocketClient(Action<OKXSocketOptions> optionsDelegate, ILoggerFactory? loggerFactory = null) : base(loggerFactory, "OKX")
34+
/// <param name="options">Option configuration delegate</param>
35+
public OKXSocketClient(IOptions<OKXSocketOptions> options, ILoggerFactory? loggerFactory = null) : base(loggerFactory, "OKX")
4136
{
42-
var options = OKXSocketOptions.Default.Copy();
43-
optionsDelegate(options);
44-
Initialize(options);
37+
Initialize(options.Value);
4538

46-
UnifiedApi = AddApiClient(new OKXSocketClientUnifiedApi(_logger, options));
39+
UnifiedApi = AddApiClient(new OKXSocketClientUnifiedApi(_logger, options.Value));
4740
}
4841
#endregion
4942

@@ -54,9 +47,7 @@ public OKXSocketClient(Action<OKXSocketOptions> optionsDelegate, ILoggerFactory?
5447
/// <param name="optionsDelegate"></param>
5548
public static void SetDefaultOptions(Action<OKXSocketOptions> optionsDelegate)
5649
{
57-
var options = OKXSocketOptions.Default.Copy();
58-
optionsDelegate(options);
59-
OKXSocketOptions.Default = options;
50+
OKXSocketOptions.Default = ApplyOptionsDelegate(optionsDelegate);
6051
}
6152

6253
/// <inheritdoc />

Diff for: OKX.Net/Clients/UnifiedApi/OKXRestClientUnifiedApi.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ internal OKXRestClientUnifiedApi(ILogger logger, HttpClient? httpClient, OKXRest
4040

4141
_ref = !string.IsNullOrEmpty(options.BrokerId) ? options.BrokerId! : "1425d83a94fbBCDE";
4242

43-
if (options.Environment.EnvironmentName == TradeEnvironmentNames.Testnet)
43+
if (options.Environment.Name == TradeEnvironmentNames.Testnet)
4444
{
4545
StandardRequestHeaders = new Dictionary<string, string>
4646
{

Diff for: OKX.Net/Clients/UnifiedApi/OKXSocketClientUnifiedApi.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ internal OKXSocketClientUnifiedApi(ILogger logger, OKXSocketOptions options) :
4545

4646
_ref = !string.IsNullOrEmpty(options.BrokerId) ? options.BrokerId! : "078ee129065aBCDE";
4747

48-
_demoTrading = options.Environment.EnvironmentName == TradeEnvironmentNames.Testnet;
48+
_demoTrading = options.Environment.Name == TradeEnvironmentNames.Testnet;
4949

5050
RegisterPeriodicQuery("Ping", TimeSpan.FromSeconds(20), x => new OKXPingQuery(), null);
5151

0 commit comments

Comments
 (0)