Discord.Net icon indicating copy to clipboard operation
Discord.Net copied to clipboard

[Bug]: `InteractionHandler.AddModulesAsync` can't resolve scoped dependencies.

Open LavaToaster opened this issue 2 years ago • 1 comments

Check The Docs

  • [X] I double checked the docs and couldn't find any useful information.

Verify Issue Source

  • [X] I verified the issue was caused by Discord.Net.

Check your intents

  • [X] I double checked that I have the required intents.

Description

When I try to add any InteractionModule, using InteractionHandler.AddModulesAsync that requires a scoped dependency, the application crashes because it's using the root provider.

I can easily fix this on my end by updating the code as follows:

- await _handler.AddModulesAsync(Assembly.GetEntryAssembly(), _services);
+ using (var scope = _services.CreateScope())
+ {
+     await _handler.AddModulesAsync(Assembly.GetEntryAssembly(), scope.ServiceProvider);
+ }

It feels that this could be handled in the library, as I can see that scopes are created when executing commands.

Version

3.7.2

Working Version

No response

Logs

Unhandled exception. System.InvalidOperationException: Cannot resolve scoped service 'TheBaron.Data.AppDbContext' from root provider.
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteValidator.ValidateResolution(Type serviceType, IServiceScope scope, IServiceScope rootScope)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
   at Discord.Interactions.ReflectionUtils`1.GetMember(InteractionService commandService, IServiceProvider services, Type memberType, TypeInfo ownerType)
   at Discord.Interactions.ReflectionUtils`1.<>c__DisplayClass2_0.<CreateBuilder>b__0(IServiceProvider services)
   at Discord.Interactions.ReflectionUtils`1.CreateObject(TypeInfo typeInfo, InteractionService commandService, IServiceProvider services)
   at Discord.Interactions.Builders.ModuleBuilder.Build(InteractionService interactionService, IServiceProvider services, ModuleInfo parent)
   at Discord.Interactions.Builders.ModuleClassBuilder.BuildAsync(IEnumerable`1 validTypes, InteractionService commandService, IServiceProvider services)
   at Discord.Interactions.InteractionService.AddModulesAsync(Assembly assembly, IServiceProvider services)
   at TheBaron.Bot.InteractionHandler.InitializeAsync() in /Users/adam/Projects/Personal/TheBaron/Bot/InteractionHandler.cs:line 35
   at TheBaron.Bot.BotService.StartAsync(CancellationToken cancellationToken) in /Users/adam/Projects/Personal/TheBaron/Bot/BotService.cs:line 26
   at Microsoft.Extensions.Hosting.Internal.Host.StartAsync(CancellationToken cancellationToken)
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.Run(IHost host)
   at Microsoft.AspNetCore.Builder.WebApplication.Run(String url)
   at Program.<Main>$(String[] args) in /Users/adam/Projects/Personal/TheBaron/Program.cs:line 76

Sample

I've got a project here https://github.com/LavaToaster/the-baron/tree/96cf014ee0f6aa41360cfc431d853687cb41b465 you can use that to provide you with something to work on. The only thing you'd need to do prior is run EF Migrations via dotnet ef database update, it's using SQLite at the moment so you won't need to spin up any other db. If you want a much smaller and more concentrated example, let me know and I'll set some time aside for it.

Packages

Here are my project dependencies:

    <ItemGroup>
        <PackageReference Include="AspNet.Security.OAuth.Discord" Version="6.0.6" />
        <PackageReference Include="AspNet.Security.OpenId.Steam" Version="6.0.0" />
        <PackageReference Include="Discord.Net" Version="3.7.2" />
        <PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.5" />
        <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.5">
            <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
            <PrivateAssets>all</PrivateAssets>
        </PackageReference>
        <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.5" />
        <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="6.0.5" />
        <PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
    </ItemGroup>

LavaToaster avatar Jun 13 '22 14:06 LavaToaster

Explanation here. And docs update were implemented on #2368 but docs aren't up to date.

Cenngo avatar Aug 01 '22 17:08 Cenngo