From a89f79e9f38ae27fa65ed6b1cfa4244f7bb65b39 Mon Sep 17 00:00:00 2001 From: Quahu Date: Sun, 28 Jul 2024 17:56:24 +0200 Subject: [PATCH] Refactor client/bot registration to support HostApplicationBuilder --- .../DiscordBotServiceCollectionExtensions.cs | 52 -------------- .../DiscordBotHostBuilderExtensions.cs | 70 +++++++++++++++++-- ...iscordClientServiceCollectionExtensions.cs | 21 ------ .../DiscordClientHostBuilderExtensions.cs | 37 ++++++++-- 4 files changed, 95 insertions(+), 85 deletions(-) diff --git a/src/Disqord.Bot/DiscordBotServiceCollectionExtensions.cs b/src/Disqord.Bot/DiscordBotServiceCollectionExtensions.cs index be74fb88d..df66fcf64 100644 --- a/src/Disqord.Bot/DiscordBotServiceCollectionExtensions.cs +++ b/src/Disqord.Bot/DiscordBotServiceCollectionExtensions.cs @@ -1,5 +1,4 @@ using System; -using System.Threading; using Disqord.Bot.Commands; using Disqord.Bot.Commands.Application; using Disqord.Bot.Commands.Application.Default; @@ -13,57 +12,6 @@ namespace Disqord.Bot; public static class DiscordBotServiceCollectionExtensions { - public static IServiceCollection AddDiscordBot(this IServiceCollection services, Action? configure = null) - { - services.AddDiscordBot(); - - var options = services.AddOptions(); - if (configure != null) - options.Configure(configure); - - return services; - } - - public static IServiceCollection AddDiscordBot(this IServiceCollection services) - where TDiscordBot : DiscordBot - { - services.AddDiscordClient(); - - if (services.TryAddSingleton()) - { - var callCount = 0; - - TDiscordBot GetBotService(IServiceProvider services) - { - if (Interlocked.Increment(ref callCount) > 1) - throw new InvalidOperationException($"Disqord detected a circular dependency for the bot client of type '{typeof(TDiscordBot)}'. " - + "This means that most likely your prefix provider or another service depends on the bot client and vice versa."); - - var service = services.GetRequiredService(); - Interlocked.Decrement(ref callCount); - return service; - } - - if (typeof(TDiscordBot) != typeof(DiscordBot)) - services.TryAddSingleton(GetBotService); - - services.TryAddSingleton(GetBotService); - services.Replace(ServiceDescriptor.Singleton(GetBotService)); - } - - services.AddDiscordBotDependencies(); - return services; - } - - internal static void AddDiscordBotDependencies(this IServiceCollection services) - { - services.AddPrefixProvider(); - services.AddCommands(); - services.AddCommandContextAccessor(); - services.AddApplicationCommandLocalizer(); - services.AddApplicationCommandCacheProvider(); - } - public static IServiceCollection AddPrefixProvider(this IServiceCollection services) where TPrefixProvider : class, IPrefixProvider { diff --git a/src/Disqord.Bot/Hosting/DiscordBotHostBuilderExtensions.cs b/src/Disqord.Bot/Hosting/DiscordBotHostBuilderExtensions.cs index bad80e87d..710e398d6 100644 --- a/src/Disqord.Bot/Hosting/DiscordBotHostBuilderExtensions.cs +++ b/src/Disqord.Bot/Hosting/DiscordBotHostBuilderExtensions.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; -using System.ComponentModel; using System.Linq; +using System.Threading; using Disqord.Bot.Commands.Text; using Disqord.DependencyInjection.Extensions; using Disqord.Hosting; @@ -33,16 +33,34 @@ public static IHostBuilder ConfigureDiscordBot(); - services.ConfigureDiscordBot(context, discordContext); - services.ConfigureDiscordClient(context, discordContext); + services.AddDiscordBot(discordContext); }); return builder; } - [EditorBrowsable(EditorBrowsableState.Never)] - public static void ConfigureDiscordBot(this IServiceCollection services, HostBuilderContext context, DiscordBotHostingContext discordContext) + public static IServiceCollection AddDiscordBot(this IServiceCollection services, DiscordBotHostingContext context) + { + return services.AddDiscordBot(context); + } + + public static IServiceCollection AddDiscordBot(this IServiceCollection services, DiscordBotHostingContext context) + where TDiscordBot : DiscordBot + { + return services.AddDiscordBot(context); + } + + public static IServiceCollection AddDiscordBot(this IServiceCollection services, DiscordBotHostingContext context) + where TDiscordBot : DiscordBot + where TDiscordBotConfiguration : DiscordBotBaseConfiguration, new() + { + services.AddDiscordBot(); + services.ConfigureDiscordBot(context); + services.ConfigureDiscordClient(context); + return services; + } + + internal static void ConfigureDiscordBot(this IServiceCollection services, DiscordBotHostingContext discordContext) where TBotConfiguration : DiscordBotBaseConfiguration, new() { if (discordContext.OwnerIds != null || discordContext.ApplicationId != null) @@ -75,4 +93,44 @@ public static void ConfigureDiscordBot(this IServiceCollectio services.TryAddSingleton(); } + + internal static IServiceCollection AddDiscordBot(this IServiceCollection services) + where TDiscordBot : DiscordBot + { + services.AddDiscordClient(); + + if (services.TryAddSingleton()) + { + var callCount = 0; + + TDiscordBot GetBotService(IServiceProvider services) + { + if (Interlocked.Increment(ref callCount) > 1) + throw new InvalidOperationException($"Disqord detected a circular dependency for the bot client of type '{typeof(TDiscordBot)}'. " + + "This means that most likely your prefix provider or another service depends on the bot client and vice versa."); + + var service = services.GetRequiredService(); + Interlocked.Decrement(ref callCount); + return service; + } + + if (typeof(TDiscordBot) != typeof(DiscordBot)) + services.TryAddSingleton(GetBotService); + + services.TryAddSingleton(GetBotService); + services.Replace(ServiceDescriptor.Singleton(GetBotService)); + } + + services.AddDiscordBotDependencies(); + return services; + } + + internal static void AddDiscordBotDependencies(this IServiceCollection services) + { + services.AddPrefixProvider(); + services.AddCommands(); + services.AddCommandContextAccessor(); + services.AddApplicationCommandLocalizer(); + services.AddApplicationCommandCacheProvider(); + } } diff --git a/src/Disqord/DiscordClientServiceCollectionExtensions.cs b/src/Disqord/DiscordClientServiceCollectionExtensions.cs index 27e189f3f..fd3d2b583 100644 --- a/src/Disqord/DiscordClientServiceCollectionExtensions.cs +++ b/src/Disqord/DiscordClientServiceCollectionExtensions.cs @@ -1,11 +1,6 @@ using System.ComponentModel; -using Disqord.Api; using Disqord.DependencyInjection.Extensions; -using Disqord.Extensions.Interactivity; -using Disqord.Gateway; using Disqord.Gateway.Api; -using Disqord.Rest; -using Disqord.Webhook; using Microsoft.Extensions.DependencyInjection; namespace Disqord; @@ -13,22 +8,6 @@ namespace Disqord; [EditorBrowsable(EditorBrowsableState.Advanced)] public static class DiscordClientServiceCollectionExtensions { - public static IServiceCollection AddDiscordClient(this IServiceCollection services) - { - if (services.TryAddSingleton()) - { - services.TryAddSingleton(services => services.GetRequiredService()); - services.AddShardCoordinator(); - } - - services.AddInteractivityExtension(); - services.AddGatewayClient(); - services.AddRestClient(); - services.AddWebhookClientFactory(); - - return services; - } - public static IServiceCollection AddShardCoordinator(this IServiceCollection services) where TShardCoordinator : class, IShardCoordinator { diff --git a/src/Disqord/Hosting/DiscordClientHostBuilderExtensions.cs b/src/Disqord/Hosting/DiscordClientHostBuilderExtensions.cs index 8fe149753..45c428f4a 100644 --- a/src/Disqord/Hosting/DiscordClientHostBuilderExtensions.cs +++ b/src/Disqord/Hosting/DiscordClientHostBuilderExtensions.cs @@ -1,11 +1,15 @@ using System; -using System.ComponentModel; using System.Linq; +using Disqord.Api; using Disqord.DependencyInjection.Extensions; +using Disqord.Extensions.Interactivity; +using Disqord.Gateway; using Disqord.Gateway.Api.Default; using Disqord.Gateway.Api.Models; using Disqord.Gateway.Default; using Disqord.Http.Default; +using Disqord.Rest; +using Disqord.Webhook; using Disqord.WebSocket.Default; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; @@ -21,16 +25,37 @@ public static IHostBuilder ConfigureDiscordClient(this IHostBuilder builder, Act var discordContext = new DiscordClientHostingContext(); configure?.Invoke(context, discordContext); - services.AddDiscordClient(); - services.AddHostedService(); - services.ConfigureDiscordClient(context, discordContext); + services.AddDiscordClient(discordContext); }); return builder; } - [EditorBrowsable(EditorBrowsableState.Never)] - public static void ConfigureDiscordClient(this IServiceCollection services, HostBuilderContext context, DiscordClientHostingContext discordContext) + public static IServiceCollection AddDiscordClient(this IServiceCollection services, DiscordClientHostingContext context) + { + services.AddDiscordClient(); + services.AddHostedService(); + services.ConfigureDiscordClient(context); + return services; + } + + internal static IServiceCollection AddDiscordClient(this IServiceCollection services) + { + if (services.TryAddSingleton()) + { + services.TryAddSingleton(services => services.GetRequiredService()); + services.AddShardCoordinator(); + } + + services.AddInteractivityExtension(); + services.AddGatewayClient(); + services.AddRestClient(); + services.AddWebhookClientFactory(); + + return services; + } + + internal static void ConfigureDiscordClient(this IServiceCollection services, DiscordClientHostingContext discordContext) { services.Replace(ServiceDescriptor.Singleton(Token.Bot(discordContext.Token!)));