Spectre.Console Extensions
A library of extensions and helpers for building powerful command-line applications with Spectre.Console. Simplify dependency injection setup, streamline app configuration, and accelerate your CLI development with production-ready components.
What is Spectre.Console Extensions?
Spectre.Console is a fantastic library for creating beautiful console applications in .NET. However, setting up dependency injection, configuring commands, and writing tests can require significant boilerplate code.
Spectre.Console Extensions eliminates that friction by providing:
- Ready-to-use dependency injection integrations for popular DI frameworks
- A fluent
CommandAppBuilderfor cleaner app configuration - Testing infrastructure to simplify unit testing your commands
- Additional UI controls for common input scenarios
Key Features
Dependency Injection Support
Out-of-the-box implementations of ITypeRegistrar and ITypeResolver
for the most popular .NET dependency injection frameworks:
CommandAppBuilder
A fluent builder pattern for creating, configuring, and running your Spectre.Console
CommandApp. Reduce boilerplate and improve readability with chainable methods.
Testing Infrastructure
The Spectre.Console.Extensions.Testing namespace provides test context classes
and helpers that simplify unit testing. Test your commands, configuration, and end-to-end
functionality with minimal setup code.
Additional Controls
Enhanced prompts and presenters for common scenarios:
| Control | Description |
|---|---|
CurrencyPrompt |
Culture-aware text prompt for currency input with validation and decimal conversion |
CurrencyPresenter |
Display currency values in a culture-aware format with abbreviations for large numbers |
HistoryTextPrompt<T> |
Text prompt with history - use arrow keys to navigate previous entries |
Table.AddSeparatorRow() |
Extension method to add separator rows to Spectre tables |
Installation
Install the NuGet packages using the Package Manager Console or .NET CLI:
# Core package (includes Microsoft.Extensions.DependencyInjection support) dotnet add package D20Tek.Spectre.Console.Extensions # Additional DI containers (Autofac, Lamar, LightInject, Ninject, SimpleInjector) dotnet add package D20Tek.Spectre.Console.Extensions.MoreContainers
The core package is designed with minimal dependencies. If you need support for other DI frameworks, add the MoreContainers package which includes TypeRegistrars for all supported frameworks.
Quick Start
Using CommandAppBuilder (Recommended)
The cleanest way to set up a Spectre.Console CLI with dependency injection:
// Program.cs
using D20Tek.Spectre.Console.Extensions;
public class Program
{
public static async Task<int> Main(string[] args)
{
return await new CommandAppBuilder()
.WithDIContainer()
.WithStartup<Startup>()
.WithDefaultCommand<DefaultCommand>()
.Build()
.RunAsync(args);
}
}Then create a Startup class to configure services and commands:
// Startup.cs
using D20Tek.Spectre.Console.Extensions;
using Spectre.Console.Cli;
internal class Startup : StartupBase
{
public override void ConfigureServices(ITypeRegistrar registrar)
{
// Register your services
registrar.Register(typeof(IMyService), typeof(MyService));
// Or use lifetime extensions
registrar.WithLifetimes().RegisterSingleton<IMyService, MyService>();
}
public override IConfigurator ConfigureCommands(IConfigurator config)
{
config.CaseSensitivity(CaseSensitivity.None);
config.SetApplicationName("my-cli");
config.AddCommand<GreetCommand>("greet")
.WithDescription("Greet someone by name");
return config;
}
}Traditional Setup
For simpler applications or more control, you can configure everything in Program.cs:
using D20Tek.Spectre.Console.Extensions.Injection;
using Microsoft.Extensions.DependencyInjection;
using Spectre.Console.Cli;
public class Program
{
public static async Task<int> Main(string[] args)
{
// Create the DI container
var services = new ServiceCollection();
services.AddSingleton<IMyService, MyService>();
var registrar = new DependencyInjectionTypeRegistrar(services);
// Create and configure the CommandApp
var app = new CommandApp<DefaultCommand>(registrar);
app.Configure(config =>
{
config.SetApplicationName("my-cli");
config.AddCommand<GreetCommand>("greet");
});
return await app.RunAsync(args);
}
}Testing Your Commands
The testing infrastructure makes it easy to write unit tests for your CLI commands.
Use CommandAppTestContext to configure and run commands in isolation:
using D20Tek.Spectre.Console.Extensions.Testing;
[TestMethod]
public void GreetCommand_WithName_ReturnsSuccess()
{
// Arrange
var context = new CommandAppTestContext();
context.Configure(config =>
{
config.Settings.ApplicationName = "Test App";
config.AddCommand<GreetCommand>("greet");
});
// Act
var result = context.Run(new[] { "greet", "--name", "World" });
// Assert
Assert.AreEqual(0, result.ExitCode);
StringAssert.Contains(result.Output, "Hello, World!");
}The test context captures output, exit codes, and command context - everything you need to verify your command behavior.
Sample Projects
Explore complete working examples in the GitHub repository:
- Basic.Cli - Simple DI setup with custom Program.cs code
- DependencyInjection.Cli - Full CommandAppBuilder usage with Microsoft DI
- Autofac.Cli - Using Autofac container
- Lamar.Cli - Using Lamar container
- LightInject.Cli - Using LightInject container
- Ninject.Cli - Using Ninject container
- SimpleInjector.Cli - Using SimpleInjector container
- NoDI.Cli - CommandAppBuilder without dependency injection
- InteractivePrompt.Cli - Interactive prompt that runs registered commands
Learn More
For a comprehensive guide on building Spectre.Console command-line applications, check out the tutorial series on our blog:
Ready to supercharge your CLI development?