discord-net / Discord.Net

An unofficial .Net wrapper for the Discord API (https://discord.com/)
https://discordnet.dev
MIT License
3.33k stars 736 forks source link

[Bug]: Keyed Services are not supported #3016

Closed Granock closed 4 weeks ago

Granock commented 1 month ago

Check The Docs

Verify Issue Source

Check your intents

Description

When using KeyedServices with Dependency-Injection Discord.Net is unable to crete the modules. Issue is caused by ReflectionUtil.GetMember method.

Version

3.16.0

Working Version

No response

Logs

2024-09-21T09:31:49.1326891 fail: AetherAssistant.Discord.ClientHostService[0]
2024-09-21T07:31:49.1650000       Error during discord client execution
2024-09-21T07:31:49.1660000       System.InvalidOperationException: Failed to create "AetherAssistant.DiscordBot.Modules.Moderation.ModerationModule", dependency "PartitionedRateLimiter`1" was not found.
2024-09-21T07:31:49.1670000          at Discord.Interactions.ReflectionUtils`1.GetMember(InteractionService commandService, IServiceProvider services, Type memberType, TypeInfo ownerType)
2024-09-21T07:31:49.1670000          at Discord.Interactions.ReflectionUtils`1.<>c__DisplayClass2_0.<CreateBuilder>b__0(IServiceProvider services)
2024-09-21T07:31:49.1680000          at Discord.Interactions.ReflectionUtils`1.CreateObject(TypeInfo typeInfo, InteractionService commandService, IServiceProvider services)
2024-09-21T07:31:49.1690000          at Discord.Interactions.Builders.ModuleBuilder.Build(InteractionService interactionService, IServiceProvider services, ModuleInfo parent)
2024-09-21T07:31:49.1710000          at Discord.Interactions.Builders.ModuleClassBuilder.BuildAsync(IEnumerable`1 validTypes, InteractionService commandService, IServiceProvider services)
2024-09-21T07:31:49.1710000          at Discord.Interactions.InteractionService.AddModulesAsync(Assembly assembly, IServiceProvider services)
2024-09-21T07:31:49.1720000          at <HostedService>
2024-09-21T07:31:49.1740000 LogRecord.Timestamp:               2024-09-21T07:31:49.1719458Z
2024-09-21T07:31:49.1750000 LogRecord.CategoryName:            AetherAssistant.Discord.ClientHostService
2024-09-21T07:31:49.1760000 LogRecord.Severity:                Error
2024-09-21T07:31:49.1770000 LogRecord.SeverityText:            Error
2024-09-21T07:31:49.1780000 LogRecord.FormattedMessage:        Error during discord client execution
2024-09-21T07:31:49.1790000 LogRecord.Body:                    Error during discord client execution
2024-09-21T07:31:49.1800000 LogRecord.Attributes (Key:Value):
2024-09-21T07:31:49.1800000     OriginalFormat (a.k.a Body): Error during discord client execution
2024-09-21T07:31:49.1810000 LogRecord.Exception:               System.InvalidOperationException: Failed to create "AetherAssistant.DiscordBot.Modules.Moderation.ModerationModule", dependency "PartitionedRateLimiter`1" was not found.
2024-09-21T07:31:49.1820000    at Discord.Interactions.ReflectionUtils`1.GetMember(InteractionService commandService, IServiceProvider services, Type memberType, TypeInfo ownerType)
2024-09-21T07:31:49.1820000    at Discord.Interactions.ReflectionUtils`1.<>c__DisplayClass2_0.<CreateBuilder>b__0(IServiceProvider services)
2024-09-21T07:31:49.1830000    at Discord.Interactions.ReflectionUtils`1.CreateObject(TypeInfo typeInfo, InteractionService commandService, IServiceProvider services)
2024-09-21T07:31:49.1840000    at Discord.Interactions.Builders.ModuleBuilder.Build(InteractionService interactionService, IServiceProvider services, ModuleInfo parent)
2024-09-21T07:31:49.1860000    at Discord.Interactions.Builders.ModuleClassBuilder.BuildAsync(IEnumerable`1 validTypes, InteractionService commandService, IServiceProvider services)
2024-09-21T07:31:49.1880000    at Discord.Interactions.InteractionService.AddModulesAsync(Assembly assembly, IServiceProvider services)
2024-09-21T07:31:49.1890000    at <HostedService>

Sample

Module-Definition:

public partial class ModerationModule([FromKeyedServices("Service1")] PartitionedRateLimiter<RateLimitKey> globalRateLimiter) : AbstractInteractionModule(globalRateLimiter);

Service-Registration:

services.AddKeyedSingleton(
  serviceKey: "Service1",
  implementationInstance: RateLimitHelper.CreateTokenBucketRateLimiter(
    tokenLimit: 5, 
    queueSize: 1, 
    tokenRegeneration: 1, 
    replenishmentPeriod: TimeSpan.FromSeconds(1))
);

Packages

Discord.Net 3.16.0

Environment

OS: win 11 10.0.22631 Architecture: x64 Dotnet: .net 8.0.400

Granock commented 1 month ago

Issue is a result of RefectionUtil.GetMember using GetService without having a case for keyed Services. this results in trying to resolve the service without a key, and as the service is only registered as a keyed service, no service can be found.

AnalogFeelings commented 4 weeks ago

Willing to pick this up.