Browse Source

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'
pull/988/head
Hsu Still 7 years ago
parent
commit
d06d67517a
No known key found for this signature in database GPG Key ID: 8601A145FDA95209
3 changed files with 38 additions and 42 deletions
  1. +36
    -40
      docs/guides/commands/commands.md
  2. +1
    -1
      docs/guides/commands/samples/command_handler.cs
  3. +1
    -1
      docs/guides/commands/samples/dependency_map_setup.cs

+ 36
- 40
docs/guides/commands/commands.md View File

@@ -1,15 +1,15 @@
# The Command Service # The Command Service


[Discord.Commands](xref:Discord.Commands) provides an Attribute-based
[Discord.Commands](xref:Discord.Commands) provides an attribute-based
command parser. command parser.


## Setup ## 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. 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. minimum.


The `CommandService` will optionally accept a [CommandServiceConfig], 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 Discord.Net's implementation of Modules is influenced heavily from
ASP.NET Core's Controller pattern. This means that the lifetime of a 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] > [!WARNING]
> **Avoid using long-running code** in your modules wherever possible. > **Avoid using long-running code** in your modules wherever possible.
@@ -67,37 +67,36 @@ By now, your module should look like this:


### Adding Commands ### 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<RuntimeResult>` depending on your use. `Task<RuntimeResult>` depending on your use.
Typically, you will want to mark this method as `async`, although it Typically, you will want to mark this method as `async`, although it
is not required. 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 Parameters, by default, are always required. To make a parameter
optional, give it a default value. To accept a comma-separated list, optional, give it a default value. To accept a comma-separated list,
set the parameter to `params Type[]`. 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 [RemainderAttribute]: xref:Discord.Commands.RemainderAttribute
[CommandAttribute]: xref:Discord.Commands.CommandAttribute [CommandAttribute]: xref:Discord.Commands.CommandAttribute
@@ -116,11 +115,10 @@ priority will be called first.


### Command Context ### 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 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 Different types of Contexts may be specified using the generic variant
of [ModuleBase]. When using a [SocketCommandContext], for example, the 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 #### Loading Modules Automatically


The Command Service can automatically discover all classes in an 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 To opt a module out of auto-loading, flag it with
[DontAutoLoadAttribute]. [DontAutoLoadAttribute].


Invoke [CommandService.AddModulesAsync] to discover modules and
install them.

[DontAutoLoadAttribute]: xref:Discord.Commands.DontAutoLoadAttribute [DontAutoLoadAttribute]: xref:Discord.Commands.DontAutoLoadAttribute
[CommandService.AddModulesAsync]: xref:Discord.Commands.CommandService.AddModulesAsync* [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 Module groups also allow you to create **nameless Commands**, where
the [CommandAttribute] is configured with no name. In this case, the 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 ### Submodules


@@ -211,20 +208,19 @@ DI when writing your modules.


### Setup ### 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)] [!code-csharp[IServiceProvider Setup](samples/dependency_map_setup.cs)]


### Usage in Modules ### Usage in Modules


In the constructor of your Module, any parameters will be filled in by 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 Any publicly settable properties will also be filled in the same
manner. manner.


+ 1
- 1
docs/guides/commands/samples/command_handler.cs View File

@@ -40,7 +40,7 @@ public class Program
// Hook the MessageReceived Event into our Command Handler // Hook the MessageReceived Event into our Command Handler
_client.MessageReceived += HandleCommandAsync; _client.MessageReceived += HandleCommandAsync;
// Discover all of the commands in this assembly and load them. // 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) private async Task HandleCommandAsync(SocketMessage messageParam)


+ 1
- 1
docs/guides/commands/samples/dependency_map_setup.cs View File

@@ -14,5 +14,5 @@ public async Task InstallAsync(DiscordSocketClient client)
.AddSingleton<DatabaseService>() .AddSingleton<DatabaseService>()
.BuildServiceProvider(); .BuildServiceProvider();
// ... // ...
await _commands.AddModulesAsync(Assembly.GetEntryAssembly());
await _commands.AddModulesAsync(Assembly.GetEntryAssembly(), _services);
} }

Loading…
Cancel
Save