-
-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Improve DI guide * Lower `injection` * Add scopes guide * Use IApplicationCommandResultHandler as an example * Add a note about the behavior of modules and autocomplete providers
- Loading branch information
Showing
7 changed files
with
95 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
9 changes: 9 additions & 0 deletions
9
Documentation/guides/services/DependencyInjection/DataModule.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
using NetCord.Services.Commands; | ||
|
||
namespace MyBot; | ||
|
||
public class DataModule(IDataProvider dataProvider) : CommandModule<CommandContext> | ||
{ | ||
[Command("data")] | ||
public string Data(int count) => string.Join(' ', dataProvider.GetData().Take(count)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
9 changes: 0 additions & 9 deletions
9
Documentation/guides/services/DependencyInjection/ExampleModule.cs
This file was deleted.
Oops, something went wrong.
11 changes: 11 additions & 0 deletions
11
Documentation/guides/services/DependencyInjection/IDataProvider.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
namespace MyBot; | ||
|
||
public interface IDataProvider | ||
{ | ||
public IReadOnlyList<string> GetData(); | ||
} | ||
|
||
public class DataProvider : IDataProvider | ||
{ | ||
public IReadOnlyList<string> GetData() => ["hello", "world"]; | ||
} |
35 changes: 35 additions & 0 deletions
35
Documentation/guides/services/DependencyInjection/Program.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
using Microsoft.Extensions.DependencyInjection; | ||
using Microsoft.Extensions.Hosting; | ||
|
||
using MyBot; | ||
|
||
using NetCord; | ||
using NetCord.Gateway; | ||
using NetCord.Hosting.Gateway; | ||
using NetCord.Hosting.Services; | ||
using NetCord.Hosting.Services.ApplicationCommands; | ||
using NetCord.Hosting.Services.Commands; | ||
using NetCord.Services.ApplicationCommands; | ||
using NetCord.Services.Commands; | ||
|
||
var builder = Host.CreateApplicationBuilder(args); | ||
|
||
builder.Services | ||
.AddSingleton<IDataProvider, DataProvider>() | ||
.AddDiscordGateway(o => o.Configuration = new() { Intents = GatewayIntents.GuildMessages | GatewayIntents.DirectMessages | GatewayIntents.MessageContent }) | ||
.AddCommands<CommandContext>() | ||
.AddApplicationCommands<SlashCommandInteraction, SlashCommandContext>(); | ||
|
||
var host = builder.Build(); | ||
|
||
host.AddModules(typeof(Program).Assembly); | ||
|
||
host.AddSlashCommand<SlashCommandContext>( | ||
name: "data", | ||
description: "Shows the data!", | ||
(IDataProvider dataProvider, SlashCommandContext context, int count) => string.Join(' ', dataProvider.GetData() | ||
.Take(count))); | ||
|
||
host.UseGatewayEventHandlers(); | ||
|
||
await host.RunAsync(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,32 @@ | ||
# Dependency Injection | ||
|
||
To use dependency injection, simply create a constructor with parameters in a module or an autocomplete provider and then pass `IServiceProvider` as the last parameter of `ExecuteAsync` or `ExecuteAutocompleteAsync` method. It is done automatically when using hosting. | ||
Dependency injection (DI) is a technique that helps make your code more modular and testable by letting you pass services from the outside. It reduces tight coupling between components, making your applications easier to maintain and extend. | ||
|
||
## Example Module | ||
[!code-cs[ExampleModule.cs](DependencyInjection/ExampleModule.cs)] | ||
## Scopes | ||
|
||
## Example Autocomplete Provider | ||
[!code-cs[ExampleAutocompleteProvider.cs](DependencyInjection/ExampleAutocompleteProvider.cs)] | ||
With `NetCord.Hosting.Services` scopes are created for each command/interaction and disposed after the command/interaction is **completely** executed by default. Therefore all code relevant to the command/interaction like for example the @NetCord.Hosting.Services.ApplicationCommands.IApplicationCommandResultHandler`1 will be executed within the same scope. | ||
|
||
You can control whether to use scopes or not by setting the `UseScopes` property in the options class. For example @NetCord.Hosting.Services.ApplicationCommands.ApplicationCommandServiceOptions`2.UseScopes for application commands. | ||
|
||
## Minimal APIs | ||
|
||
Dependency injection with minimal APIs can seem complicated at first, but it is actually quite simple. | ||
|
||
What you need to know is that parameters preceding the context parameter are treated as services and parameters following the context parameter are treated as command/interaction parameters. When the context parameter is not present, all parameters are treated as command/interaction parameters. | ||
|
||
You can see an example slash command below, but the same rules apply to all services: | ||
[!code-cs[Program.cs](DependencyInjection/Program.cs#L27-L31)] | ||
|
||
## Modules | ||
|
||
Dependency injection with modules is like everywhere else. You just inject the services via the constructor. The modules behave as if they were transient services, so they are created for each command/interaction. | ||
|
||
You can see an example with text commands below, but the same rules apply to all services: | ||
[!code-cs[DataModule.cs](DependencyInjection/DataModule.cs#l5-L9)] | ||
|
||
## Autocomplete Providers | ||
|
||
Same for autocomplete providers, you just inject the services via the constructor. They also behave as if they were transient services. | ||
|
||
You can see an example autocomplete provider below: | ||
[!code-cs[DataAutocompleteProvider.cs](DependencyInjection/DataAutocompleteProvider.cs#l7-L22)] |