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 CommandAppBuilder for 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:

Microsoft.Extensions.DependencyInjection Core Package
Autofac MoreContainers
Lamar MoreContainers
LightInject MoreContainers
Ninject MoreContainers
SimpleInjector MoreContainers

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:

Building CLI Apps with Spectre.Console

Ready to supercharge your CLI development?

An unhandled error has occurred. Reload 🗙