Skip to content

Commit 613936b

Browse files
authored
build DiscordClient on top of IOC (#1908)
* centralize the service provider * prepare the rest client for IOC * obsolete all the old events... * obsolete SocketErrored even more * enables registering event handlers to the service collection * fix event-related build errors * make DiscordApiClient IOC-constructible * death (migrate events (not dispatch yet) to the interim model) * update DiscordClient.Dipshit.cs * fix most trivial build errors * more progress towards usability * DSharpPlus.dll should now work:tm: * build? * miser, miser * add public construction code * update docs * convenience * details * migration guide (partial, only as far as this PR is concerned) * build * switch to CreateDefault * nit
1 parent 4f9368a commit 613936b

File tree

179 files changed

+6059
-4461
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

179 files changed

+6059
-4461
lines changed

DSharpPlus.Commands/CommandsConfiguration.cs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,10 @@
1-
using System;
2-
31
namespace DSharpPlus.Commands;
42

53
/// <summary>
64
/// The configuration copied to an instance of <see cref="CommandsExtension"/>.
75
/// </summary>
86
public sealed record CommandsConfiguration
97
{
10-
/// <summary>
11-
/// The service provider to use for dependency injection.
12-
/// </summary>
13-
public required IServiceProvider ServiceProvider { get; set; }
14-
158
/// <summary>
169
/// The guild id to use for debugging. Leave as 0 to disable.
1710
/// </summary>

DSharpPlus.Commands/CommandsExtension.cs

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using System.Runtime.CompilerServices;
99
using System.Text;
1010
using System.Threading.Tasks;
11+
1112
using DSharpPlus.AsyncEvents;
1213
using DSharpPlus.Commands.ContextChecks;
1314
using DSharpPlus.Commands.ContextChecks.ParameterChecks;
@@ -23,16 +24,18 @@
2324
using DSharpPlus.Commands.Trees.Metadata;
2425
using DSharpPlus.Entities;
2526
using DSharpPlus.Exceptions;
27+
2628
using Microsoft.Extensions.DependencyInjection;
2729
using Microsoft.Extensions.Logging;
28-
using Microsoft.Extensions.Logging.Abstractions;
30+
2931
using CheckFunc = System.Func
3032
<
3133
object,
3234
DSharpPlus.Commands.ContextChecks.ContextCheckAttribute,
3335
DSharpPlus.Commands.CommandContext,
3436
System.Threading.Tasks.ValueTask<string?>
3537
>;
38+
3639
using ParameterCheckFunc = System.Func
3740
<
3841
object,
@@ -49,8 +52,8 @@ namespace DSharpPlus.Commands;
4952
/// </summary>
5053
public sealed class CommandsExtension : BaseExtension
5154
{
52-
/// <inheritdoc cref="CommandsConfiguration.ServiceProvider"/>
53-
public IServiceProvider ServiceProvider { get; init; }
55+
/// <inheritdoc cref="DiscordClient.ServiceProvider"/>
56+
public IServiceProvider ServiceProvider { get; private set; }
5457

5558
/// <inheritdoc cref="CommandsConfiguration.DebugGuildId"/>
5659
public ulong DebugGuildId { get; init; }
@@ -84,19 +87,29 @@ public sealed class CommandsExtension : BaseExtension
8487
/// <summary>
8588
/// Executed everytime a command is finished executing.
8689
/// </summary>
87-
public event AsyncEventHandler<CommandsExtension, CommandExecutedEventArgs> CommandExecuted { add => this.commandExecuted.Register(value); remove => this.commandExecuted.Unregister(value); }
88-
internal readonly AsyncEvent<CommandsExtension, CommandExecutedEventArgs> commandExecuted = new("COMMANDS_COMMAND_EXECUTED", EverythingWentWrongErrorHandler);
90+
public event AsyncEventHandler<CommandsExtension, CommandExecutedEventArgs> CommandExecuted
91+
{
92+
add => this.commandExecuted.Register(value);
93+
remove => this.commandExecuted.Unregister(value);
94+
}
95+
96+
internal AsyncEvent<CommandsExtension, CommandExecutedEventArgs> commandExecuted;
8997

9098
/// <summary>
9199
/// Executed everytime a command has errored.
92100
/// </summary>
93-
public event AsyncEventHandler<CommandsExtension, CommandErroredEventArgs> CommandErrored { add => this.commandErrored.Register(value); remove => this.commandErrored.Unregister(value); }
94-
internal readonly AsyncEvent<CommandsExtension, CommandErroredEventArgs> commandErrored = new("COMMANDS_COMMAND_ERRORED", EverythingWentWrongErrorHandler);
101+
public event AsyncEventHandler<CommandsExtension, CommandErroredEventArgs> CommandErrored
102+
{
103+
add => this.commandErrored.Register(value);
104+
remove => this.commandErrored.Unregister(value);
105+
}
106+
107+
internal AsyncEvent<CommandsExtension, CommandErroredEventArgs> commandErrored;
95108

96109
/// <summary>
97110
/// Used to log messages from this extension.
98111
/// </summary>
99-
private readonly ILogger<CommandsExtension> logger;
112+
private ILogger<CommandsExtension> logger;
100113

101114
/// <summary>
102115
/// Creates a new instance of the <see cref="CommandsExtension"/> class.
@@ -106,18 +119,10 @@ internal CommandsExtension(CommandsConfiguration configuration)
106119
{
107120
ArgumentNullException.ThrowIfNull(configuration);
108121

109-
this.ServiceProvider = configuration.ServiceProvider;
110122
this.DebugGuildId = configuration.DebugGuildId;
111123
this.UseDefaultCommandErrorHandler = configuration.UseDefaultCommandErrorHandler;
112124
this.RegisterDefaultCommandProcessors = configuration.RegisterDefaultCommandProcessors;
113125
this.CommandExecutor = configuration.CommandExecutor;
114-
if (this.UseDefaultCommandErrorHandler)
115-
{
116-
this.CommandErrored += DefaultCommandErrorHandlerAsync;
117-
}
118-
119-
// Attempt to get the user defined logging, otherwise setup a null logger since the D#+ Default Logger is internal.
120-
this.logger = this.ServiceProvider.GetService<ILogger<CommandsExtension>>() ?? NullLogger<CommandsExtension>.Instance;
121126
}
122127

123128
/// <summary>
@@ -136,8 +141,20 @@ protected override void Setup(DiscordClient client)
136141
}
137142

138143
this.Client = client;
144+
this.ServiceProvider = client.ServiceProvider;
139145
this.Client.SessionCreated += async (_, _) => await RefreshAsync();
140146

147+
this.logger = client.ServiceProvider.GetService<ILogger<CommandsExtension>>();
148+
149+
DefaultClientErrorHandler errorHandler = new(client.Logger);
150+
this.commandErrored = new(errorHandler);
151+
this.commandExecuted = new(errorHandler);
152+
153+
if (this.UseDefaultCommandErrorHandler)
154+
{
155+
this.CommandErrored += DefaultCommandErrorHandlerAsync;
156+
}
157+
141158
AddCheck<DirectMessageUsageCheck>();
142159
AddCheck<RequireApplicationOwnerCheck>();
143160
AddCheck<RequireGuildCheck>();

DSharpPlus.Commands/Converters/BooleanConverter.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@ public class BooleanConverter : ISlashArgumentConverter<bool>, ITextArgumentConv
1313
public bool RequiresText => true;
1414

1515
/// <inheritdoc/>
16-
public Task<Optional<bool>> ConvertAsync(TextConverterContext context, MessageCreateEventArgs eventArgs) => Task.FromResult(context.Argument.ToLowerInvariant() switch
16+
public Task<Optional<bool>> ConvertAsync(TextConverterContext context, MessageCreatedEventArgs eventArgs) => Task.FromResult(context.Argument.ToLowerInvariant() switch
1717
{
1818
"true" or "yes" or "y" or "1" or "on" or "enable" or "enabled" or "t" => Optional.FromValue(true),
1919
"false" or "no" or "n" or "0" or "off" or "disable" or "disabled" or "f" => Optional.FromValue(false),
2020
_ => Optional.FromNoValue<bool>()
2121
});
2222

23-
public Task<Optional<bool>> ConvertAsync(InteractionConverterContext context, InteractionCreateEventArgs eventArgs)
23+
public Task<Optional<bool>> ConvertAsync(InteractionConverterContext context, InteractionCreatedEventArgs eventArgs)
2424
{
2525
return bool.TryParse(context.Argument.RawValue, out bool result)
2626
? Task.FromResult(Optional.FromValue(result))

DSharpPlus.Commands/Converters/ByteConverter.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@ public class ByteConverter : ISlashArgumentConverter<byte>, ITextArgumentConvert
1313
public string ReadableName => "Positive Tiny Integer";
1414
public bool RequiresText => true;
1515

16-
public Task<Optional<byte>> ConvertAsync(TextConverterContext context, MessageCreateEventArgs eventArgs) => byte.TryParse(context.Argument, CultureInfo.InvariantCulture, out byte result)
16+
public Task<Optional<byte>> ConvertAsync(TextConverterContext context, MessageCreatedEventArgs eventArgs) => byte.TryParse(context.Argument, CultureInfo.InvariantCulture, out byte result)
1717
? Task.FromResult(Optional.FromValue(result))
1818
: Task.FromResult(Optional.FromNoValue<byte>());
1919

20-
public Task<Optional<byte>> ConvertAsync(InteractionConverterContext context, InteractionCreateEventArgs eventArgs) => byte.TryParse(context.Argument.RawValue, CultureInfo.InvariantCulture, out byte result)
20+
public Task<Optional<byte>> ConvertAsync(InteractionConverterContext context, InteractionCreatedEventArgs eventArgs) => byte.TryParse(context.Argument.RawValue, CultureInfo.InvariantCulture, out byte result)
2121
? Task.FromResult(Optional.FromValue(result))
2222
: Task.FromResult(Optional.FromNoValue<byte>());
2323
}

DSharpPlus.Commands/Converters/DateTimeOffsetConverter.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ public class DateTimeOffsetConverter : ISlashArgumentConverter<DateTimeOffset>,
1414
public string ReadableName => "Date and Time";
1515
public bool RequiresText => true;
1616

17-
public Task<Optional<DateTimeOffset>> ConvertAsync(TextConverterContext context, MessageCreateEventArgs eventArgs) => DateTimeOffset.TryParse(context.Argument, CultureInfo.InvariantCulture, out DateTimeOffset result)
17+
public Task<Optional<DateTimeOffset>> ConvertAsync(TextConverterContext context, MessageCreatedEventArgs eventArgs) => DateTimeOffset.TryParse(context.Argument, CultureInfo.InvariantCulture, out DateTimeOffset result)
1818
? Task.FromResult(Optional.FromValue(result))
1919
: Task.FromResult(Optional.FromNoValue<DateTimeOffset>());
2020

21-
public Task<Optional<DateTimeOffset>> ConvertAsync(InteractionConverterContext context, InteractionCreateEventArgs eventArgs) => DateTimeOffset.TryParse(context.Argument.RawValue, CultureInfo.InvariantCulture, out DateTimeOffset result)
21+
public Task<Optional<DateTimeOffset>> ConvertAsync(InteractionConverterContext context, InteractionCreatedEventArgs eventArgs) => DateTimeOffset.TryParse(context.Argument.RawValue, CultureInfo.InvariantCulture, out DateTimeOffset result)
2222
? Task.FromResult(Optional.FromValue(result))
2323
: Task.FromResult(Optional.FromNoValue<DateTimeOffset>());
2424
}

DSharpPlus.Commands/Converters/DiscordAttachmentConverter.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public class AttachmentConverter : ISlashArgumentConverter<DiscordAttachment>, I
1515
public string ReadableName => "Discord File";
1616
public bool RequiresText => false;
1717

18-
public Task<Optional<DiscordAttachment>> ConvertAsync(TextConverterContext context, MessageCreateEventArgs eventArgs)
18+
public Task<Optional<DiscordAttachment>> ConvertAsync(TextConverterContext context, MessageCreatedEventArgs eventArgs)
1919
{
2020
DiscordMessage message = eventArgs.Message;
2121
int currentAttachmentArgumentIndex = context.Command.Parameters.Where(argument => argument.Type == typeof(DiscordAttachment)).IndexOf(context.Parameter);
@@ -37,7 +37,7 @@ public Task<Optional<DiscordAttachment>> ConvertAsync(TextConverterContext conte
3737
: Task.FromResult(Optional.FromValue(message.Attachments[currentAttachmentArgumentIndex]));
3838
}
3939

40-
public Task<Optional<DiscordAttachment>> ConvertAsync(InteractionConverterContext context, InteractionCreateEventArgs eventArgs)
40+
public Task<Optional<DiscordAttachment>> ConvertAsync(InteractionConverterContext context, InteractionCreatedEventArgs eventArgs)
4141
{
4242
int currentAttachmentArgumentIndex = context.Command.Parameters.Where(argument => argument.Type == typeof(DiscordAttachment)).IndexOf(context.Parameter);
4343
if (eventArgs.Interaction.Data.Resolved is null)

DSharpPlus.Commands/Converters/DiscordChannelConverter.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public partial class DiscordChannelConverter : ISlashArgumentConverter<DiscordCh
1919
public string ReadableName => "Discord Channel";
2020
public bool RequiresText => true;
2121

22-
public Task<Optional<DiscordChannel>> ConvertAsync(TextConverterContext context, MessageCreateEventArgs eventArgs)
22+
public Task<Optional<DiscordChannel>> ConvertAsync(TextConverterContext context, MessageCreatedEventArgs eventArgs)
2323
{
2424
// Attempt to parse the channel id
2525
if (!ulong.TryParse(context.Argument, CultureInfo.InvariantCulture, out ulong channelId))
@@ -52,7 +52,7 @@ public Task<Optional<DiscordChannel>> ConvertAsync(TextConverterContext context,
5252
return Task.FromResult(Optional.FromNoValue<DiscordChannel>());
5353
}
5454

55-
public Task<Optional<DiscordChannel>> ConvertAsync(InteractionConverterContext context, InteractionCreateEventArgs eventArgs) => context.Interaction.Data.Resolved is null
55+
public Task<Optional<DiscordChannel>> ConvertAsync(InteractionConverterContext context, InteractionCreatedEventArgs eventArgs) => context.Interaction.Data.Resolved is null
5656
|| !ulong.TryParse(context.Argument.RawValue, CultureInfo.InvariantCulture, out ulong channelId)
5757
|| !context.Interaction.Data.Resolved.Channels.TryGetValue(channelId, out DiscordChannel? channel)
5858
? Task.FromResult(Optional.FromNoValue<DiscordChannel>())

DSharpPlus.Commands/Converters/DiscordEmojiConverter.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ public class DiscordEmojiConverter : ISlashArgumentConverter<DiscordEmoji>, ITex
1212
public string ReadableName => "Discord Emoji";
1313
public bool RequiresText => true;
1414

15-
public Task<Optional<DiscordEmoji>> ConvertAsync(TextConverterContext context, MessageCreateEventArgs eventArgs) => ConvertAsync(context, context.Argument);
16-
public Task<Optional<DiscordEmoji>> ConvertAsync(InteractionConverterContext context, InteractionCreateEventArgs eventArgs) => ConvertAsync(context, context.Argument.RawValue);
15+
public Task<Optional<DiscordEmoji>> ConvertAsync(TextConverterContext context, MessageCreatedEventArgs eventArgs) => ConvertAsync(context, context.Argument);
16+
public Task<Optional<DiscordEmoji>> ConvertAsync(InteractionConverterContext context, InteractionCreatedEventArgs eventArgs) => ConvertAsync(context, context.Argument.RawValue);
1717
public static Task<Optional<DiscordEmoji>> ConvertAsync(ConverterContext context, string? value) => !string.IsNullOrWhiteSpace(value)
1818
&& (DiscordEmoji.TryFromUnicode(context.Client, value, out DiscordEmoji? emoji) || DiscordEmoji.TryFromName(context.Client, value, out emoji))
1919
? Task.FromResult(Optional.FromValue(emoji))

DSharpPlus.Commands/Converters/DiscordMemberConverter.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public partial class DiscordMemberConverter : ISlashArgumentConverter<DiscordMem
2525

2626
public DiscordMemberConverter(ILogger<DiscordMemberConverter>? logger = null) => this.logger = logger ?? NullLogger<DiscordMemberConverter>.Instance;
2727

28-
public async Task<Optional<DiscordMember>> ConvertAsync(TextConverterContext context, MessageCreateEventArgs eventArgs)
28+
public async Task<Optional<DiscordMember>> ConvertAsync(TextConverterContext context, MessageCreatedEventArgs eventArgs)
2929
{
3030
if (context.Guild is null)
3131
{
@@ -55,7 +55,7 @@ public async Task<Optional<DiscordMember>> ConvertAsync(TextConverterContext con
5555
}
5656
}
5757

58-
public Task<Optional<DiscordMember>> ConvertAsync(InteractionConverterContext context, InteractionCreateEventArgs eventArgs) => context.Interaction.Data.Resolved is null
58+
public Task<Optional<DiscordMember>> ConvertAsync(InteractionConverterContext context, InteractionCreatedEventArgs eventArgs) => context.Interaction.Data.Resolved is null
5959
|| !ulong.TryParse(context.Argument.RawValue, CultureInfo.InvariantCulture, out ulong memberId)
6060
|| !context.Interaction.Data.Resolved.Members.TryGetValue(memberId, out DiscordMember? member)
6161
? Task.FromResult(Optional.FromNoValue<DiscordMember>())

DSharpPlus.Commands/Converters/DiscordMessageConverter.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ public partial class DiscordMessageConverter : ISlashArgumentConverter<DiscordMe
1818
public string ReadableName => "Discord Message Link";
1919
public bool RequiresText => true;
2020

21-
public Task<Optional<DiscordMessage>> ConvertAsync(TextConverterContext context, MessageCreateEventArgs eventArgs) => ConvertAsync(context, context.Argument);
22-
public Task<Optional<DiscordMessage>> ConvertAsync(InteractionConverterContext context, InteractionCreateEventArgs eventArgs) => ConvertAsync(context, context.Argument.RawValue);
21+
public Task<Optional<DiscordMessage>> ConvertAsync(TextConverterContext context, MessageCreatedEventArgs eventArgs) => ConvertAsync(context, context.Argument);
22+
public Task<Optional<DiscordMessage>> ConvertAsync(InteractionConverterContext context, InteractionCreatedEventArgs eventArgs) => ConvertAsync(context, context.Argument.RawValue);
2323

2424
public static async Task<Optional<DiscordMessage>> ConvertAsync(ConverterContext context, string? value)
2525
{

0 commit comments

Comments
 (0)