From 33b728e53e6fba4cc549f1ca5cd37c917f587ba0 Mon Sep 17 00:00:00 2001 From: KubaZ2 Date: Sat, 14 Jun 2025 11:55:09 +0200 Subject: [PATCH 1/3] Use `IHttpClientFactory` is available in hosting packages --- .../Gateway/GatewayClientOptions.cs | 6 +-- .../NetCord.Hosting/Rest/RestClientOptions.cs | 43 ++++++++++++++++++- .../NetCord.Test.Hosting.csproj | 1 + Tests/NetCord.Test.Hosting/Program.cs | 1 + 4 files changed, 46 insertions(+), 5 deletions(-) diff --git a/Hosting/NetCord.Hosting/Gateway/GatewayClientOptions.cs b/Hosting/NetCord.Hosting/Gateway/GatewayClientOptions.cs index f7f1e518d..21c07f390 100644 --- a/Hosting/NetCord.Hosting/Gateway/GatewayClientOptions.cs +++ b/Hosting/NetCord.Hosting/Gateway/GatewayClientOptions.cs @@ -7,7 +7,7 @@ using NetCord.Gateway.LatencyTimers; using NetCord.Gateway.ReconnectStrategies; using NetCord.Gateway.WebSockets; -using NetCord.Rest; +using NetCord.Hosting.Rest; namespace NetCord.Hosting.Gateway; @@ -66,7 +66,7 @@ internal partial class Validator : IValidateOptions public Shard? Shard { get; set; } /// - public RestClientConfiguration? RestClientConfiguration { get; set; } + public RestClientOptions RestClientOptions { get; } = new(); internal GatewayClientConfiguration CreateConfiguration(IServiceProvider services) { @@ -84,7 +84,7 @@ internal GatewayClientConfiguration CreateConfiguration(IServiceProvider service LargeThreshold, Presence, Shard, - RestClientConfiguration, + RestClientOptions.CreateConfiguration(services), new GatewayMicrosoftExtensionsLogger(services)); } } diff --git a/Hosting/NetCord.Hosting/Rest/RestClientOptions.cs b/Hosting/NetCord.Hosting/Rest/RestClientOptions.cs index 54f7260af..61f5a895e 100644 --- a/Hosting/NetCord.Hosting/Rest/RestClientOptions.cs +++ b/Hosting/NetCord.Hosting/Rest/RestClientOptions.cs @@ -1,4 +1,6 @@ -using NetCord.Rest; +using System.Reflection; + +using NetCord.Rest; using NetCord.Rest.RateLimits; namespace NetCord.Hosting.Rest; @@ -26,14 +28,51 @@ public class RestClientOptions : IDiscordOptions internal RestClientConfiguration CreateConfiguration(IServiceProvider services) { + var requestHandler = RequestHandler ?? CreateDefaultRequestHandler(services); + return new() { Hostname = Hostname, Version = Version, - RequestHandler = RequestHandler, + RequestHandler = requestHandler, DefaultRequestProperties = DefaultRequestProperties, RateLimitManager = RateLimitManager, Logger = new RestMicrosoftExtensionsLogger(services), }; } + + private static MicrosoftExtensionsRestRequestHandler? CreateDefaultRequestHandler(IServiceProvider services) + { + var factoryType = Type.GetType("System.Net.Http.IHttpClientFactory,Microsoft.Extensions.Http"); + if (factoryType is not null) + { + var method = factoryType.GetMethod("CreateClient", BindingFlags.Public | BindingFlags.Instance, [typeof(string)]); + if (method is null || method.ReturnType != typeof(HttpClient)) + return null; // Wrong type + + if (services.GetService(factoryType) is { } factory) + { + var client = (HttpClient)method.Invoke(factory, [nameof(RestClient)])!; + + return new(client); + } + } + + return null; + } +} + +internal sealed class MicrosoftExtensionsRestRequestHandler(HttpClient httpClient) : IRestRequestHandler +{ + public Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken = default) => httpClient.SendAsync(request, cancellationToken); + + public void AddDefaultHeader(string name, IEnumerable values) + { + httpClient.DefaultRequestHeaders.Add(name, values); + } + + public void Dispose() + { + httpClient.Dispose(); + } } diff --git a/Tests/NetCord.Test.Hosting/NetCord.Test.Hosting.csproj b/Tests/NetCord.Test.Hosting/NetCord.Test.Hosting.csproj index ef4624e6a..1d122a5bd 100644 --- a/Tests/NetCord.Test.Hosting/NetCord.Test.Hosting.csproj +++ b/Tests/NetCord.Test.Hosting/NetCord.Test.Hosting.csproj @@ -11,6 +11,7 @@ + diff --git a/Tests/NetCord.Test.Hosting/Program.cs b/Tests/NetCord.Test.Hosting/Program.cs index 9b4f28825..2139ecee4 100644 --- a/Tests/NetCord.Test.Hosting/Program.cs +++ b/Tests/NetCord.Test.Hosting/Program.cs @@ -39,6 +39,7 @@ var builder = Host.CreateApplicationBuilder(args); builder.Services + .AddHttpClient() .ConfigureDiscordGateway(o => o.Presence = new(UserStatusType.DoNotDisturb)) .ConfigureCommands(o => o.Prefix = "!") .ConfigureCommands(o => o.Prefix = ">") From bf11f7d315d62b1199f6348315c21d4da2f2ccc0 Mon Sep 17 00:00:00 2001 From: KubaZ2 Date: Sat, 14 Jun 2025 11:56:54 +0200 Subject: [PATCH 2/3] Refactor CreateConfiguration --- Hosting/NetCord.Hosting/Rest/RestClientOptions.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Hosting/NetCord.Hosting/Rest/RestClientOptions.cs b/Hosting/NetCord.Hosting/Rest/RestClientOptions.cs index 61f5a895e..207a02526 100644 --- a/Hosting/NetCord.Hosting/Rest/RestClientOptions.cs +++ b/Hosting/NetCord.Hosting/Rest/RestClientOptions.cs @@ -28,13 +28,11 @@ public class RestClientOptions : IDiscordOptions internal RestClientConfiguration CreateConfiguration(IServiceProvider services) { - var requestHandler = RequestHandler ?? CreateDefaultRequestHandler(services); - return new() { Hostname = Hostname, Version = Version, - RequestHandler = requestHandler, + RequestHandler = RequestHandler ?? CreateDefaultRequestHandler(services), DefaultRequestProperties = DefaultRequestProperties, RateLimitManager = RateLimitManager, Logger = new RestMicrosoftExtensionsLogger(services), From 73b4310d4b5f141a252f686709b3a2b67f8353a8 Mon Sep 17 00:00:00 2001 From: KubaZ2 Date: Sat, 14 Jun 2025 11:59:18 +0200 Subject: [PATCH 3/3] Normalize naming and refactor --- .../Gateway/GatewayClientOptions.cs | 2 +- ....cs => MicrosoftExtensionsGatewayLogger.cs} | 2 +- ...MicrosoftExtensionsShardedGatewayLogger.cs} | 2 +- .../Gateway/ShardedGatewayClientOptions.cs | 4 ++-- ...ger.cs => MicrosoftExtensionsRestLogger.cs} | 5 ++--- .../MicrosoftExtensionsRestRequestHandler.cs | 18 ++++++++++++++++++ .../NetCord.Hosting/Rest/RestClientOptions.cs | 17 +---------------- 7 files changed, 26 insertions(+), 24 deletions(-) rename Hosting/NetCord.Hosting/Gateway/{GatewayMicrosoftExtensionsLogger.cs => MicrosoftExtensionsGatewayLogger.cs} (93%) rename Hosting/NetCord.Hosting/Gateway/{ShardedGatewayMicrosoftExtensionsLogger.cs => MicrosoftExtensionsShardedGatewayLogger.cs} (90%) rename Hosting/NetCord.Hosting/Rest/{RestMicrosoftExtensionsLogger.cs => MicrosoftExtensionsRestLogger.cs} (84%) create mode 100644 Hosting/NetCord.Hosting/Rest/MicrosoftExtensionsRestRequestHandler.cs diff --git a/Hosting/NetCord.Hosting/Gateway/GatewayClientOptions.cs b/Hosting/NetCord.Hosting/Gateway/GatewayClientOptions.cs index 21c07f390..fb4adf82a 100644 --- a/Hosting/NetCord.Hosting/Gateway/GatewayClientOptions.cs +++ b/Hosting/NetCord.Hosting/Gateway/GatewayClientOptions.cs @@ -85,6 +85,6 @@ internal GatewayClientConfiguration CreateConfiguration(IServiceProvider service Presence, Shard, RestClientOptions.CreateConfiguration(services), - new GatewayMicrosoftExtensionsLogger(services)); + new MicrosoftExtensionsGatewayLogger(services)); } } diff --git a/Hosting/NetCord.Hosting/Gateway/GatewayMicrosoftExtensionsLogger.cs b/Hosting/NetCord.Hosting/Gateway/MicrosoftExtensionsGatewayLogger.cs similarity index 93% rename from Hosting/NetCord.Hosting/Gateway/GatewayMicrosoftExtensionsLogger.cs rename to Hosting/NetCord.Hosting/Gateway/MicrosoftExtensionsGatewayLogger.cs index d3b0d8f06..887403d5e 100644 --- a/Hosting/NetCord.Hosting/Gateway/GatewayMicrosoftExtensionsLogger.cs +++ b/Hosting/NetCord.Hosting/Gateway/MicrosoftExtensionsGatewayLogger.cs @@ -7,7 +7,7 @@ namespace NetCord.Hosting.Gateway; -internal class GatewayMicrosoftExtensionsLogger(IServiceProvider services) : IGatewayLogger, IRestLogger +internal class MicrosoftExtensionsGatewayLogger(IServiceProvider services) : IGatewayLogger, IRestLogger { private readonly ILogger _gatewayLogger = services.GetRequiredService>(); private readonly ILogger _restLogger = services.GetRequiredService>(); diff --git a/Hosting/NetCord.Hosting/Gateway/ShardedGatewayMicrosoftExtensionsLogger.cs b/Hosting/NetCord.Hosting/Gateway/MicrosoftExtensionsShardedGatewayLogger.cs similarity index 90% rename from Hosting/NetCord.Hosting/Gateway/ShardedGatewayMicrosoftExtensionsLogger.cs rename to Hosting/NetCord.Hosting/Gateway/MicrosoftExtensionsShardedGatewayLogger.cs index 319e30b1d..f1a9c29f2 100644 --- a/Hosting/NetCord.Hosting/Gateway/ShardedGatewayMicrosoftExtensionsLogger.cs +++ b/Hosting/NetCord.Hosting/Gateway/MicrosoftExtensionsShardedGatewayLogger.cs @@ -6,7 +6,7 @@ namespace NetCord.Hosting.Gateway; -internal class ShardedGatewayMicrosoftExtensionsLogger(int shardId, IServiceProvider services) : IGatewayLogger +internal class MicrosoftExtensionsShardedGatewayLogger(int shardId, IServiceProvider services) : IGatewayLogger { private readonly ILogger _gatewayLogger = services.GetRequiredService>(); private readonly EventId _eventId = new(shardId); diff --git a/Hosting/NetCord.Hosting/Gateway/ShardedGatewayClientOptions.cs b/Hosting/NetCord.Hosting/Gateway/ShardedGatewayClientOptions.cs index 4534bd064..e443e089e 100644 --- a/Hosting/NetCord.Hosting/Gateway/ShardedGatewayClientOptions.cs +++ b/Hosting/NetCord.Hosting/Gateway/ShardedGatewayClientOptions.cs @@ -144,9 +144,9 @@ internal ShardedGatewayClientConfiguration CreateConfiguration(IServiceProvider IGatewayLogger? CreateLogger(Shard? shard) { if (shard.HasValue) - return new ShardedGatewayMicrosoftExtensionsLogger(shard.GetValueOrDefault().Id, services); + return new MicrosoftExtensionsShardedGatewayLogger(shard.GetValueOrDefault().Id, services); - return new RestMicrosoftExtensionsLogger(services); + return new MicrosoftExtensionsRestLogger(services); } } } diff --git a/Hosting/NetCord.Hosting/Rest/RestMicrosoftExtensionsLogger.cs b/Hosting/NetCord.Hosting/Rest/MicrosoftExtensionsRestLogger.cs similarity index 84% rename from Hosting/NetCord.Hosting/Rest/RestMicrosoftExtensionsLogger.cs rename to Hosting/NetCord.Hosting/Rest/MicrosoftExtensionsRestLogger.cs index c83826839..e4448db1b 100644 --- a/Hosting/NetCord.Hosting/Rest/RestMicrosoftExtensionsLogger.cs +++ b/Hosting/NetCord.Hosting/Rest/MicrosoftExtensionsRestLogger.cs @@ -1,5 +1,4 @@ - -using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using NetCord.Logging; @@ -7,7 +6,7 @@ namespace NetCord.Hosting.Rest; -internal class RestMicrosoftExtensionsLogger(IServiceProvider services) : IRestLogger, IGatewayLogger +internal class MicrosoftExtensionsRestLogger(IServiceProvider services) : IRestLogger, IGatewayLogger { private readonly ILogger _logger = services.GetRequiredService>(); diff --git a/Hosting/NetCord.Hosting/Rest/MicrosoftExtensionsRestRequestHandler.cs b/Hosting/NetCord.Hosting/Rest/MicrosoftExtensionsRestRequestHandler.cs new file mode 100644 index 000000000..4d753994e --- /dev/null +++ b/Hosting/NetCord.Hosting/Rest/MicrosoftExtensionsRestRequestHandler.cs @@ -0,0 +1,18 @@ +using NetCord.Rest; + +namespace NetCord.Hosting.Rest; + +internal sealed class MicrosoftExtensionsRestRequestHandler(HttpClient httpClient) : IRestRequestHandler +{ + public Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken = default) => httpClient.SendAsync(request, cancellationToken); + + public void AddDefaultHeader(string name, IEnumerable values) + { + httpClient.DefaultRequestHeaders.Add(name, values); + } + + public void Dispose() + { + httpClient.Dispose(); + } +} diff --git a/Hosting/NetCord.Hosting/Rest/RestClientOptions.cs b/Hosting/NetCord.Hosting/Rest/RestClientOptions.cs index 207a02526..6ed07e6e7 100644 --- a/Hosting/NetCord.Hosting/Rest/RestClientOptions.cs +++ b/Hosting/NetCord.Hosting/Rest/RestClientOptions.cs @@ -35,7 +35,7 @@ internal RestClientConfiguration CreateConfiguration(IServiceProvider services) RequestHandler = RequestHandler ?? CreateDefaultRequestHandler(services), DefaultRequestProperties = DefaultRequestProperties, RateLimitManager = RateLimitManager, - Logger = new RestMicrosoftExtensionsLogger(services), + Logger = new MicrosoftExtensionsRestLogger(services), }; } @@ -59,18 +59,3 @@ internal RestClientConfiguration CreateConfiguration(IServiceProvider services) return null; } } - -internal sealed class MicrosoftExtensionsRestRequestHandler(HttpClient httpClient) : IRestRequestHandler -{ - public Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken = default) => httpClient.SendAsync(request, cancellationToken); - - public void AddDefaultHeader(string name, IEnumerable values) - { - httpClient.DefaultRequestHeaders.Add(name, values); - } - - public void Dispose() - { - httpClient.Dispose(); - } -}