From d06d67517a8c3f4017bd70c0f05f24d9e004bdd8 Mon Sep 17 00:00:00 2001 From: Hsu Still <341464@gmail.com> Date: Fri, 23 Mar 2018 14:17:21 +0800 Subject: [PATCH] Improve readability & general fixes Notable changes include the following, + Add _services into examples. + Rename Commands back to commands. - This was changed in my previous PR; however, this made readability really weird. + Fix broken examples. + Directly referencing anchors instead of saying 'see this below' --- docs/guides/commands/commands.md | 76 +++++++++---------- .../commands/samples/command_handler.cs | 2 +- .../commands/samples/dependency_map_setup.cs | 2 +- 3 files changed, 38 insertions(+), 42 deletions(-) diff --git a/docs/guides/commands/commands.md b/docs/guides/commands/commands.md index 896843621..4999e2b9d 100644 --- a/docs/guides/commands/commands.md +++ b/docs/guides/commands/commands.md @@ -1,15 +1,15 @@ # The Command Service -[Discord.Commands](xref:Discord.Commands) provides an Attribute-based +[Discord.Commands](xref:Discord.Commands) provides an attribute-based command parser. ## Setup -To use Commands, you must create a [Command Service] and a Command +To use Commands, you must create a [Command Service] and a command Handler. -Included below is a very barebone Command Handler. You can extend your -Command Handler as much as you like; however, the below is the bare +Included below is a very barebone command handler. You can extend your +command Handler as much as you like; however, the below is the bare minimum. The `CommandService` will optionally accept a [CommandServiceConfig], @@ -39,7 +39,7 @@ Commands in different classes and have them automatically loaded. Discord.Net's implementation of Modules is influenced heavily from ASP.NET Core's Controller pattern. This means that the lifetime of a -module instance is only as long as the Command is being invoked. +module instance is only as long as the command is being invoked. > [!WARNING] > **Avoid using long-running code** in your modules wherever possible. @@ -67,37 +67,36 @@ By now, your module should look like this: ### Adding Commands -The next step to creating Commands is actually creating the Commands. +The next step to creating commands is actually creating the commands. -To create a Command, add a method to your module of type `Task` or +To create a command, add a method to your module of type `Task` or `Task` depending on your use. Typically, you will want to mark this method as `async`, although it is not required. -Adding parameters to a Command is done by adding parameters to the -parent Task. - -For example, to take an integer as an argument from the user, add `int -arg`; to take a user as an argument from the user, add `IUser user`. -Starting from 1.0, a Command can accept nearly any type of argument; -a full list of types that are parsed by default can be found in -the below section on [Type Readers](#type-readers). +Adding parameters to a command is done by adding parameters to the +parent Task. For example, to take an integer as an argument from +the user, add `int arg`; to take a user as an argument from the +user, add `IUser user`. Starting from 1.0, a command can accept +nearly any type of argument; a full list of types that are parsed +by default can be found in the below +section on [Type Readers](#type-readers). Parameters, by default, are always required. To make a parameter optional, give it a default value. To accept a comma-separated list, set the parameter to `params Type[]`. -Should a parameter include spaces, it **must** be wrapped in quotes. -For example, for a Command with a parameter `string food`, you would -execute it with `!favoritefood "Key Lime Pie"`. - -If you would like a parameter to parse until the end of a Command, -flag the parameter with the [RemainderAttribute]. This will allow a -user to invoke a Command without wrapping a parameter in quotes. +Should a parameter include spaces, the parameter **must** be +wrapped in quotes. For example, for a command with a parameter +`string food`, you would execute it with +`!favoritefood "Key Lime Pie"`. If you would like a parameter to +parse until the end of a command, flag the parameter with the +[RemainderAttribute]. This will allow a user to invoke a command +without wrapping a parameter in quotes. -Finally, flag your Command with the [CommandAttribute]. (you must -specify a name for this Command, except for when it is part of a -Module Group - see below) +Finally, flag your command with the [CommandAttribute] (you must +specify a name for this command, except for when it is part of a +[Module Group](#module-groups). [RemainderAttribute]: xref:Discord.Commands.RemainderAttribute [CommandAttribute]: xref:Discord.Commands.CommandAttribute @@ -116,11 +115,10 @@ priority will be called first. ### Command Context -Every Command can access the execution context through the [Context] +Every command can access the execution context through the [Context] property on [ModuleBase]. `ICommandContext` allows you to access the -message, channel, guild, and user that the Command was invoked from, -as well as the underlying Discord client that the Command was invoked -from. +message, channel, guild, user, and the underlying Discord client +that the command was invoked from. Different types of Contexts may be specified using the generic variant of [ModuleBase]. When using a [SocketCommandContext], for example, the @@ -146,14 +144,13 @@ At this point, your module should look comparable to this example: #### Loading Modules Automatically The Command Service can automatically discover all classes in an -Assembly that inherit [ModuleBase] and load them. +Assembly that inherit [ModuleBase] and load them. Invoke +[CommandService.AddModulesAsync] to discover modules and +install them. To opt a module out of auto-loading, flag it with [DontAutoLoadAttribute]. -Invoke [CommandService.AddModulesAsync] to discover modules and -install them. - [DontAutoLoadAttribute]: xref:Discord.Commands.DontAutoLoadAttribute [CommandService.AddModulesAsync]: xref:Discord.Commands.CommandService.AddModulesAsync* @@ -189,7 +186,7 @@ prefixed. To create a group, flag a module with the Module groups also allow you to create **nameless Commands**, where the [CommandAttribute] is configured with no name. In this case, the -Command will inherit the name of the group it belongs to. +command will inherit the name of the group it belongs to. ### Submodules @@ -211,20 +208,19 @@ DI when writing your modules. ### Setup -First, you need to create an @System.IServiceProvider; you may create -your own one if you wish. +First, you need to create an @System.IServiceProvider. -Next, add the dependencies that your modules will use to the map. +Next, add the dependencies to the service collection that you wish +to use in the Modules. -Finally, pass the map into the `LoadAssembly` method. Your modules -will be automatically loaded with this dependency map. +Finally, pass the service collection into `AddModulesAsync`. [!code-csharp[IServiceProvider Setup](samples/dependency_map_setup.cs)] ### Usage in Modules In the constructor of your Module, any parameters will be filled in by -the @System.IServiceProvider that you've passed into `LoadAssembly`. +the @System.IServiceProvider that you've passed. Any publicly settable properties will also be filled in the same manner. diff --git a/docs/guides/commands/samples/command_handler.cs b/docs/guides/commands/samples/command_handler.cs index da2453aa8..1e68d70ec 100644 --- a/docs/guides/commands/samples/command_handler.cs +++ b/docs/guides/commands/samples/command_handler.cs @@ -40,7 +40,7 @@ public class Program // Hook the MessageReceived Event into our Command Handler _client.MessageReceived += HandleCommandAsync; // Discover all of the commands in this assembly and load them. - await _commands.AddModulesAsync(Assembly.GetEntryAssembly()); + await _commands.AddModulesAsync(Assembly.GetEntryAssembly(), _services); } private async Task HandleCommandAsync(SocketMessage messageParam) diff --git a/docs/guides/commands/samples/dependency_map_setup.cs b/docs/guides/commands/samples/dependency_map_setup.cs index a36925904..34e4c994e 100644 --- a/docs/guides/commands/samples/dependency_map_setup.cs +++ b/docs/guides/commands/samples/dependency_map_setup.cs @@ -14,5 +14,5 @@ public async Task InstallAsync(DiscordSocketClient client) .AddSingleton() .BuildServiceProvider(); // ... - await _commands.AddModulesAsync(Assembly.GetEntryAssembly()); + await _commands.AddModulesAsync(Assembly.GetEntryAssembly(), _services); } \ No newline at end of file