Consider leaving a ⭐
Do more, with less. With speed, compatibility and fluent integration in mind.
Commands.NET aims to improve your experience integrating input from different sources* into the same, concurrent pool and treating them as triggered actions, called commands. It provides a modular and intuitive API for registering and executing commands.
Browse the wiki for a full overview of the library.
*Sources can range from command-line, console, chatboxes, to social platforms like Discord, Slack, Messenger & much, much more.
A command is a method executed when a specific syntax is provided. By creating a manager to contain said command, you can run it with the provided arguments.
using Commands;
var command = Command.From(() => "Hello world!", "greet");
var collection = ComponentCollection.With.Component(command).Create();
await collection.Execute(new ConsoleContext(args));
// dotnet run greet -> Hello world!
Command groups are named collections of commands or other command groups. Groups allow for subcommand creation, where the group name is a category for its children.
using Commands;
var mathCommands = CommandGroup.From("math")
.Components(
Command.From((double number, int sumBy) => number + sumBy,
"sum", "add"),
Command.From((double number, int subtractBy) => number - subtractBy,
"subtract", "sub"),
Command.From((double number, int multiplyBy) => number * multiplyBy,
"multiply", "mul"),
Command.From((double number, int divideBy) => number / divideBy,
"divide", "div")
);
var collection = ComponentCollection.With.Components(mathCommands).Create();
await collection.Execute(new ConsoleContext(args));
// dotnet run math sum 5 3 -> 8
Command modules are classes that can contain commands or nested command modules, which themselves can also contain (sub)commands.
using Commands;
public class HelpModule : CommandModule
{
[Name("help")]
public void Help()
{
var builder = new StringBuilder()
.AppendLine("Commands:");
foreach (var command in Manager!.GetCommands())
builder.AppendLine(command.GetFullName());
Respond(builder.ToString());
}
}
...
var collection = ComponentCollection.With.Component(mathCommands).Type<HelpModule>().Create();
await collection.Execute(new ConsoleContext(args));
// dotnet run help -> Commands: math sum <...> math subtract <...> math ...
Commands.NET is designed to be compatible with dependency injection out of the box, propagating IServiceProvider
throughout the execution flow.
using Commands;
using Microsoft.Extensions.DependencyInjection;
...
var services = new ServiceCollection()
.AddSingleton<MyService>()
.AddSingleton<ComponentCollection>(ComponentCollection.With.Component(mathCommands).Type<HelpModule>().Create());
.BuildServiceProvider();
var collection = services.GetRequiredService<ComponentCollection>();
await collection.Execute(new ConsoleContext(args), new CommandOptions() { Services = services });
Modules can be injected directly from the provider. They themselves are considered transient, being created and disposed of per command execution.
public class ServicedModule(MyService service) : CommandModule
{
}
- Commands.Samples.Core
- Manage, create and execute commands in a basic console application.
- Commands.Samples.Console
- Fluent API's, complex execution flow and workflow expansion.
- Commands.Samples.Hosting
- Integrating Commands.NET into the .NET Generic Host infrastructure.
Benchmark results are found here.