Browse Source

Update cmd docs to use IServiceProvider

tags/1.0
Bond_009 8 years ago
parent
commit
892eca39fd
3 changed files with 31 additions and 29 deletions
  1. +10
    -11
      docs/guides/commands/commands.md
  2. +17
    -13
      docs/guides/commands/samples/command_handler.cs
  3. +4
    -5
      docs/guides/commands/samples/dependency_map_setup.cs

+ 10
- 11
docs/guides/commands/commands.md View File

@@ -45,7 +45,7 @@ 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 being invoked.

**Avoid using long-running code** in your modules whereever possible.
**Avoid using long-running code** in your modules wherever possible.
You should **not** be implementing very much logic into your modules;
outsource to a service for that.

@@ -167,8 +167,8 @@ a dependency map.

Modules are constructed using Dependency Injection. Any parameters
that are placed in the constructor must be injected into an
@Discord.Commands.IDependencyMap. Alternatively, you may accept an
IDependencyMap as an argument and extract services yourself.
@System.IServiceProvider. Alternatively, you may accept an
IServiceProvider as an argument and extract services yourself.

### Module Properties

@@ -205,21 +205,20 @@ you use DI when writing your modules.

### Setup

First, you need to create an @Discord.Commands.IDependencyMap.
The library includes @Discord.Commands.DependencyMap to help with
this, however you may create your own IDependencyMap if you wish.
First, you need to create an @System.IServiceProvider
You may create your own IServiceProvider if you wish.

Next, add the dependencies your modules will use to the map.

Finally, pass the map into the `LoadAssembly` method.
Your modules will automatically be loaded with this dependency map.

[!code-csharp[DependencyMap Setup](samples/dependency_map_setup.cs)]
[!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 @Discord.Commands.IDependencyMap you pass into `LoadAssembly`.
the @System.IServiceProvider you pass into `LoadAssembly`.

Any publicly settable properties will also be filled in the same manner.

@@ -228,12 +227,12 @@ Any publicly settable properties will also be filled in the same manner.
being injected.

>[!NOTE]
>If you accept `CommandService` or `IDependencyMap` as a parameter in
>If you accept `CommandService` or `IServiceProvider` as a parameter in
your constructor or as an injectable property, these entries will be filled
by the CommandService the module was loaded from, and the DependencyMap passed
by the CommandService the module was loaded from, and the ServiceProvider passed
into it, respectively.

[!code-csharp[DependencyMap in Modules](samples/dependency_module.cs)]
[!code-csharp[ServiceProvider in Modules](samples/dependency_module.cs)]

# Preconditions



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

@@ -1,14 +1,16 @@
using System;
using System.Threading.Tasks;
using System.Reflection;
using Discord;
using Discord.WebSocket;
using Discord.Commands;
using Microsoft.Extensions.DependencyInjection;

public class Program
{
private CommandService commands;
private DiscordSocketClient client;
private DependencyMap map;
private IServiceProvider services;

static void Main(string[] args) => new Program().Start().GetAwaiter().GetResult();

@@ -19,38 +21,40 @@ public class Program

string token = "bot token here";

map = new DependencyMap();
services = new ServiceCollection()
.BuildServiceProvider();

await InstallCommands();

await client.LoginAsync(TokenType.Bot, token);
await client.ConnectAsync();
await client.StartAsync();

await Task.Delay(-1);
}

public async Task InstallCommands()
{
// Hook the MessageReceived Event into our Command Handler
client.MessageReceived += HandleCommand;
// 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());
}

public async Task HandleCommand(SocketMessage messageParam)
{
{
// Don't process the command if it was a System Message
var message = messageParam as SocketUserMessage;
if (message == null) return;
// Create a number to track where the prefix ends and the command begins
int argPos = 0;
// Determine if the message is a command, based on if it starts with '!' or a mention prefix
if (!(message.HasCharPrefix('!', ref argPos) || message.HasMentionPrefix(client.CurrentUser, ref argPos))) return;
// Create a number to track where the prefix ends and the command begins
int argPos = 0;
// Determine if the message is a command, based on if it starts with '!' or a mention prefix
if (!(message.HasCharPrefix('!', ref argPos) || message.HasMentionPrefix(client.CurrentUser, ref argPos))) return;
// Create a Command Context
var context = new CommandContext(client, message);
// Execute the command. (result does not indicate a return value,
// rather an object stating if the command executed succesfully)
var result = await commands.ExecuteAsync(context, argPos, map);
// rather an object stating if the command executed successfully)
var result = await commands.ExecuteAsync(context, argPos, service);
if (!result.IsSuccess)
await context.Channel.SendMessageAsync(result.ErrorReason);
}

}
}

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

@@ -7,12 +7,11 @@ public class Commands
{
public async Task Install(DiscordSocketClient client)
{
// Here, we will inject the Dependency Map with
// Here, we will inject the ServiceProvider with
// all of the services our client will use.
_map.Add(client);
_map.Add(commands);
_map.Add(new NotificationService(_map));
_map.Add(new DatabaseService(_map));
_serviceCollection.AddSingleton(client)
_serviceCollection.AddSingleton(new NotificationService())
_serviceCollection.AddSingleton(new DatabaseService())
// ...
await _commands.AddModulesAsync(Assembly.GetEntryAssembly());
}


Loading…
Cancel
Save