Skip to content

Commit b63b6bf

Browse files
committed
Added user provider implementation
1 parent fd90abf commit b63b6bf

File tree

4 files changed

+219
-0
lines changed

4 files changed

+219
-0
lines changed
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
using HTX.Net.Interfaces.Clients;
2+
using HTX.Net.Objects.Options;
3+
using CryptoExchange.Net.Authentication;
4+
using Microsoft.Extensions.DependencyInjection;
5+
using Microsoft.Extensions.Logging;
6+
using Microsoft.Extensions.Options;
7+
using System;
8+
using System.Collections.Concurrent;
9+
using System.Net.Http;
10+
using System.Collections.Generic;
11+
12+
namespace HTX.Net.Clients
13+
{
14+
/// <inheritdoc />
15+
public class HTXUserClientProvider : IHTXUserClientProvider
16+
{
17+
private static ConcurrentDictionary<string, IHTXRestClient> _restClients = new ConcurrentDictionary<string, IHTXRestClient>();
18+
private static ConcurrentDictionary<string, IHTXSocketClient> _socketClients = new ConcurrentDictionary<string, IHTXSocketClient>();
19+
20+
private readonly IOptions<HTXRestOptions> _restOptions;
21+
private readonly IOptions<HTXSocketOptions> _socketOptions;
22+
private readonly HttpClient _httpClient;
23+
private readonly ILoggerFactory? _loggerFactory;
24+
25+
/// <summary>
26+
/// ctor
27+
/// </summary>
28+
/// <param name="optionsDelegate">Options to use for created clients</param>
29+
public HTXUserClientProvider(Action<HTXOptions>? optionsDelegate = null)
30+
: this(null, null, Options.Create(ApplyOptionsDelegate(optionsDelegate).Rest), Options.Create(ApplyOptionsDelegate(optionsDelegate).Socket))
31+
{
32+
}
33+
34+
/// <summary>
35+
/// ctor
36+
/// </summary>
37+
public HTXUserClientProvider(
38+
HttpClient? httpClient,
39+
ILoggerFactory? loggerFactory,
40+
IOptions<HTXRestOptions> restOptions,
41+
IOptions<HTXSocketOptions> socketOptions)
42+
{
43+
_httpClient = httpClient ?? new HttpClient();
44+
_loggerFactory = loggerFactory;
45+
_restOptions = restOptions;
46+
_socketOptions = socketOptions;
47+
}
48+
49+
/// <inheritdoc />
50+
public void InitializeUserClient(string userIdentifier, ApiCredentials credentials, HTXEnvironment? environment = null)
51+
{
52+
CreateRestClient(userIdentifier, credentials, environment);
53+
CreateSocketClient(userIdentifier, credentials, environment);
54+
}
55+
56+
/// <inheritdoc />
57+
public IHTXRestClient GetRestClient(string userIdentifier, ApiCredentials? credentials = null, HTXEnvironment? environment = null)
58+
{
59+
if (!_restClients.TryGetValue(userIdentifier, out var client))
60+
client = CreateRestClient(userIdentifier, credentials, environment);
61+
62+
return client;
63+
}
64+
65+
/// <inheritdoc />
66+
public IHTXSocketClient GetSocketClient(string userIdentifier, ApiCredentials? credentials = null, HTXEnvironment? environment = null)
67+
{
68+
if (!_socketClients.TryGetValue(userIdentifier, out var client))
69+
client = CreateSocketClient(userIdentifier, credentials, environment);
70+
71+
return client;
72+
}
73+
74+
private IHTXRestClient CreateRestClient(string userIdentifier, ApiCredentials? credentials, HTXEnvironment? environment)
75+
{
76+
var clientRestOptions = SetRestEnvironment(environment);
77+
var client = new HTXRestClient(_httpClient, _loggerFactory, clientRestOptions);
78+
if (credentials != null)
79+
{
80+
client.SetApiCredentials(credentials);
81+
_restClients.TryAdd(userIdentifier, client);
82+
}
83+
return client;
84+
}
85+
86+
private IHTXSocketClient CreateSocketClient(string userIdentifier, ApiCredentials? credentials, HTXEnvironment? environment)
87+
{
88+
var clientSocketOptions = SetSocketEnvironment(environment);
89+
var client = new HTXSocketClient(clientSocketOptions!, _loggerFactory);
90+
if (credentials != null)
91+
{
92+
client.SetApiCredentials(credentials);
93+
_socketClients.TryAdd(userIdentifier, client);
94+
}
95+
return client;
96+
}
97+
98+
private IOptions<HTXRestOptions> SetRestEnvironment(HTXEnvironment? environment)
99+
{
100+
if (environment == null)
101+
return _restOptions;
102+
103+
var newRestClientOptions = new HTXRestOptions();
104+
var restOptions = _restOptions.Value.Set(newRestClientOptions);
105+
newRestClientOptions.Environment = environment;
106+
return Options.Create(newRestClientOptions);
107+
}
108+
109+
private IOptions<HTXSocketOptions> SetSocketEnvironment(HTXEnvironment? environment)
110+
{
111+
if (environment == null)
112+
return _socketOptions;
113+
114+
var newSocketClientOptions = new HTXSocketOptions();
115+
var restOptions = _socketOptions.Value.Set(newSocketClientOptions);
116+
newSocketClientOptions.Environment = environment;
117+
return Options.Create(newSocketClientOptions);
118+
}
119+
120+
private static T ApplyOptionsDelegate<T>(Action<T>? del) where T : new()
121+
{
122+
var opts = new T();
123+
del?.Invoke(opts);
124+
return opts;
125+
}
126+
}
127+
}

HTX.Net/ExtensionMethods/ServiceCollectionExtensions.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,12 @@ private static IServiceCollection AddHTXCore(
117117
services.AddTransient<ICryptoSocketClient, CryptoSocketClient>();
118118
services.AddTransient<IHTXOrderBookFactory, HTXOrderBookFactory>();
119119
services.AddTransient<IHTXTrackerFactory, HTXTrackerFactory>();
120+
services.AddSingleton<IHTXUserClientProvider, HTXUserClientProvider>(x =>
121+
new HTXUserClientProvider(
122+
x.GetRequiredService<HttpClient>(),
123+
x.GetRequiredService<ILoggerFactory>(),
124+
x.GetRequiredService<IOptions<HTXRestOptions>>(),
125+
x.GetRequiredService<IOptions<HTXSocketOptions>>()));
120126

121127
services.RegisterSharedRestInterfaces(x => x.GetRequiredService<IHTXRestClient>().SpotApi.SharedClient);
122128
services.RegisterSharedSocketInterfaces(x => x.GetRequiredService<IHTXSocketClient>().SpotApi.SharedClient);

HTX.Net/HTX.Net.xml

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,29 @@
7373
<member name="M:HTX.Net.Clients.HTXSocketClient.SetApiCredentials(CryptoExchange.Net.Authentication.ApiCredentials)">
7474
<inheritdoc />
7575
</member>
76+
<member name="T:HTX.Net.Clients.HTXUserClientProvider">
77+
<inheritdoc />
78+
</member>
79+
<member name="M:HTX.Net.Clients.HTXUserClientProvider.#ctor(System.Action{HTX.Net.Objects.Options.HTXOptions})">
80+
<summary>
81+
ctor
82+
</summary>
83+
<param name="optionsDelegate">Options to use for created clients</param>
84+
</member>
85+
<member name="M:HTX.Net.Clients.HTXUserClientProvider.#ctor(System.Net.Http.HttpClient,Microsoft.Extensions.Logging.ILoggerFactory,Microsoft.Extensions.Options.IOptions{HTX.Net.Objects.Options.HTXRestOptions},Microsoft.Extensions.Options.IOptions{HTX.Net.Objects.Options.HTXSocketOptions})">
86+
<summary>
87+
ctor
88+
</summary>
89+
</member>
90+
<member name="M:HTX.Net.Clients.HTXUserClientProvider.InitializeUserClient(System.String,CryptoExchange.Net.Authentication.ApiCredentials,HTX.Net.HTXEnvironment)">
91+
<inheritdoc />
92+
</member>
93+
<member name="M:HTX.Net.Clients.HTXUserClientProvider.GetRestClient(System.String,CryptoExchange.Net.Authentication.ApiCredentials,HTX.Net.HTXEnvironment)">
94+
<inheritdoc />
95+
</member>
96+
<member name="M:HTX.Net.Clients.HTXUserClientProvider.GetSocketClient(System.String,CryptoExchange.Net.Authentication.ApiCredentials,HTX.Net.HTXEnvironment)">
97+
<inheritdoc />
98+
</member>
7699
<member name="T:HTX.Net.Clients.SpotApi.HTXRestClientSpotApi">
77100
<inheritdoc />
78101
</member>
@@ -8021,6 +8044,35 @@
80218044
</summary>
80228045
<param name="credentials">The credentials to set</param>
80238046
</member>
8047+
<member name="T:HTX.Net.Interfaces.Clients.IHTXUserClientProvider">
8048+
<summary>
8049+
Provider for clients with credentials for specific users
8050+
</summary>
8051+
</member>
8052+
<member name="M:HTX.Net.Interfaces.Clients.IHTXUserClientProvider.InitializeUserClient(System.String,CryptoExchange.Net.Authentication.ApiCredentials,HTX.Net.HTXEnvironment)">
8053+
<summary>
8054+
Initialize a client for the specified user identifier. This can be used so to initialize a client for a user so ApiCredentials do not need to be passed later.
8055+
</summary>
8056+
<param name="userIdentifier">The identifier for the user</param>
8057+
<param name="credentials">The credentials for the user</param>
8058+
<param name="environment">The environment to use</param>
8059+
</member>
8060+
<member name="M:HTX.Net.Interfaces.Clients.IHTXUserClientProvider.GetRestClient(System.String,CryptoExchange.Net.Authentication.ApiCredentials,HTX.Net.HTXEnvironment)">
8061+
<summary>
8062+
Get the Rest client for a specific user. In case the client does not exist yet it will be created and the <paramref name="credentials"/> should be provided, unless <see cref="M:HTX.Net.Interfaces.Clients.IHTXUserClientProvider.InitializeUserClient(System.String,CryptoExchange.Net.Authentication.ApiCredentials,HTX.Net.HTXEnvironment)" /> has been called prior for this user.
8063+
</summary>
8064+
<param name="userIdentifier">The identifier for user</param>
8065+
<param name="credentials">The credentials for the user. Required the first time a client is requested for this user unless <see cref="M:HTX.Net.Interfaces.Clients.IHTXUserClientProvider.InitializeUserClient(System.String,CryptoExchange.Net.Authentication.ApiCredentials,HTX.Net.HTXEnvironment)" /> has been called prior for this user.</param>
8066+
<param name="environment">The environment to use</param>
8067+
</member>
8068+
<member name="M:HTX.Net.Interfaces.Clients.IHTXUserClientProvider.GetSocketClient(System.String,CryptoExchange.Net.Authentication.ApiCredentials,HTX.Net.HTXEnvironment)">
8069+
<summary>
8070+
Get the Socket client for a specific user. In case the client does not exist yet it will be created and the <paramref name="credentials"/> should be provided, unless <see cref="M:HTX.Net.Interfaces.Clients.IHTXUserClientProvider.InitializeUserClient(System.String,CryptoExchange.Net.Authentication.ApiCredentials,HTX.Net.HTXEnvironment)" /> has been called prior for this user.
8071+
</summary>
8072+
<param name="userIdentifier">The identifier for user</param>
8073+
<param name="credentials">The credentials for the user. Required the first time a client is requested for this user unless <see cref="M:HTX.Net.Interfaces.Clients.IHTXUserClientProvider.InitializeUserClient(System.String,CryptoExchange.Net.Authentication.ApiCredentials,HTX.Net.HTXEnvironment)" /> has been called prior for this user.</param>
8074+
<param name="environment">The environment to use</param>
8075+
</member>
80248076
<member name="T:HTX.Net.Interfaces.Clients.SpotApi.IHTXRestClientSpotApi">
80258077
<summary>
80268078
Spot API endpoints
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
using CryptoExchange.Net.Authentication;
2+
3+
namespace HTX.Net.Interfaces.Clients
4+
{
5+
/// <summary>
6+
/// Provider for clients with credentials for specific users
7+
/// </summary>
8+
public interface IHTXUserClientProvider
9+
{
10+
/// <summary>
11+
/// Initialize a client for the specified user identifier. This can be used so to initialize a client for a user so ApiCredentials do not need to be passed later.
12+
/// </summary>
13+
/// <param name="userIdentifier">The identifier for the user</param>
14+
/// <param name="credentials">The credentials for the user</param>
15+
/// <param name="environment">The environment to use</param>
16+
void InitializeUserClient(string userIdentifier, ApiCredentials credentials, HTXEnvironment? environment = null);
17+
18+
/// <summary>
19+
/// Get the Rest client for a specific user. In case the client does not exist yet it will be created and the <paramref name="credentials"/> should be provided, unless <see cref="InitializeUserClient" /> has been called prior for this user.
20+
/// </summary>
21+
/// <param name="userIdentifier">The identifier for user</param>
22+
/// <param name="credentials">The credentials for the user. Required the first time a client is requested for this user unless <see cref="InitializeUserClient" /> has been called prior for this user.</param>
23+
/// <param name="environment">The environment to use</param>
24+
IHTXRestClient GetRestClient(string userIdentifier, ApiCredentials? credentials = null, HTXEnvironment? environment = null);
25+
26+
/// <summary>
27+
/// Get the Socket client for a specific user. In case the client does not exist yet it will be created and the <paramref name="credentials"/> should be provided, unless <see cref="InitializeUserClient" /> has been called prior for this user.
28+
/// </summary>
29+
/// <param name="userIdentifier">The identifier for user</param>
30+
/// <param name="credentials">The credentials for the user. Required the first time a client is requested for this user unless <see cref="InitializeUserClient" /> has been called prior for this user.</param>
31+
/// <param name="environment">The environment to use</param>
32+
IHTXSocketClient GetSocketClient(string userIdentifier, ApiCredentials? credentials = null, HTXEnvironment? environment = null);
33+
}
34+
}

0 commit comments

Comments
 (0)