D20Tek.Spectre.Console.Extensions.MoreContainers 1.50.1.7

dotnet add package D20Tek.Spectre.Console.Extensions.MoreContainers --version 1.50.1.7
                    
NuGet\Install-Package D20Tek.Spectre.Console.Extensions.MoreContainers -Version 1.50.1.7
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="D20Tek.Spectre.Console.Extensions.MoreContainers" Version="1.50.1.7" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="D20Tek.Spectre.Console.Extensions.MoreContainers" Version="1.50.1.7" />
                    
Directory.Packages.props
<PackageReference Include="D20Tek.Spectre.Console.Extensions.MoreContainers" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add D20Tek.Spectre.Console.Extensions.MoreContainers --version 1.50.1.7
                    
#r "nuget: D20Tek.Spectre.Console.Extensions.MoreContainers, 1.50.1.7"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package D20Tek.Spectre.Console.Extensions.MoreContainers@1.50.1.7
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=D20Tek.Spectre.Console.Extensions.MoreContainers&version=1.50.1.7
                    
Install as a Cake Addin
#tool nuget:?package=D20Tek.Spectre.Console.Extensions.MoreContainers&version=1.50.1.7
                    
Install as a Cake Tool

d20Tek Spectre.Console Extensions

CI Build Official Build NuGet Release

Introduction

This package provides extensions for common code and patterns when using Spectre.Console CLI app framework SpectreConsole.

The current releases contain implementations of ITypeRegistrar and ITypeResolver for the following DI frameworks:

  • Microsoft.Extensions.DependencyInjection
  • Autofac
  • Lamar
  • LightInject
  • Ninject

We also support the CommandAppBuilder to easily create, configure, and run your instance of Spectre.Console.CommandApp.

The new Spectre.Console.Extensions.Testing namespace supports test infrastructure classes to easily test commands, configuration, and end-to-end functionaly runs. There are various CommandAppTextContext classes and helpers that simplify unit test boilerplate code.

Additional Spectre Controls:

  • CurrencyPrompt - TextPrompt (culture-aware) for currency input validation and conversion to decimal value.
  • CurrencyPresenter - show currency in a culture-aware way, including abbreviations for large values.
  • HistoryTextPrompt<T> - duplicates TextPrompt and add ability to remember previous entries and use arrow up/down keys to navigate the list.
  • Table extension to add a separator row.

Note: Only Microsoft.Extensions.DependencyInjection is implemented in the core extensions package (D20Tek.Spectre.Console.Extensions). The other DI containers have been repackaged into D20Tek.Spectre.Console.Extensions.MoreContainers, so that we could minimize the dependencies of the core package, and only add those dependencies for users that want to use one of those other frameworks. And, our TypeRegistrars continue to work for those different frameworks.

For future releases, I will continue to investigate integration with other DI frameworks and logging integrations.

Installation

This libraries are NuGet packages so they are easy to add to your project. To install these packages into your solution, you can use the NuGet Package Manager. In PM, please use the following command:

PM > Install-Package D20Tek.Spectre.Console.Extensions -Version 1.50.7
PM > Install-Package D20Tek.Spectre.Console.Extensions.MoreContainers -Version 1.50.7

To install in the Visual Studio UI, go to the Tools menu > "Manage NuGet Packages". Then search for D20Tek.Spectre.Console.Extensions and install it from there.

Read more about the current release in our Release Notes.

Usage

Once you've installed the NuGet package, you can start using it in your Spectre.Console projects. If you would like basic information about how to build Spectre.Console CommandApps, please read: https://darthpedro.net/lessons-cli/.

To add dependency injection into a CommandApp using the CommandAppBuilder, you can do the following in Program.cs:

using D20Tek.Samples.Common.Commands;
using D20Tek.Spectre.Console.Extensions;

namespace DependencyInjection.Cli
{
    public class Program
    {
        public static async Task<int> Main(string[] args)
        {
            return await new CommandAppBuilder()
                             .WithDIContainer()
                             .WithStartup<Startup>()
                             .WithDefaultCommand<DefaultCommand>()
                             .Build()
                             .RunAsync(args);
        }
    }
}

And, you will need to create the following Startup.cs file:

using D20Tek.Samples.Common.Commands;
using D20Tek.Samples.Common.Services;
using D20Tek.Spectre.Console.Extensions;
using Spectre.Console.Cli;

namespace DependencyInjection.Cli
{
    internal class Startup : StartupBase
    {
        public override void ConfigureServices(ITypeRegistrar registrar)
        {
            // register services here...
            registrar.Register(typeof(IDisplayWriter), typeof(ConsoleDisplayWriter));
            // or use registration extensions on WithLifetimes() to specify the container's ServiceLifetime.
            // registrar.WithLifetimes().RegisterSingleton<IDisplayWriter, ConsoleDisplayWriter>();
        }

        public override IConfigurator ConfigureCommands(IConfigurator config)
        {
            config.CaseSensitivity(CaseSensitivity.None);
            config.SetApplicationName("DependencyInjection.Cli");
            config.ValidateExamples();

            config.AddCommand<DefaultCommand>("default")
                .WithDescription("Default command that displays some text.")
                .WithExample(new[] { "default", "--verbose", "high" });

            return config;
        }
    }
}

With Custom Code in Program

You do not need to use the CommandAppBuilder. It is still possible to write custom code your Program.Main method. And that can be simpler for small console applications.

To add dependency injection this way, you can do the following:

using D20Tek.Samples.Common.Commands;
using D20Tek.Samples.Common.Services;
using D20Tek.Spectre.Console.Extensions.Injection;
using Microsoft.Extensions.DependencyInjection;
using Spectre.Console.Cli;

namespace D20Tek.CountryService.Cli
{
    public class Program
    {
        public static async Task<int> Main(string[] args)
        {
            // Create the DI container.
            var services = new ServiceCollection();

            // configure services here...
            services.AddSingleton<IDisplayWriter, ConsoleDisplayWriter>();
            var registrar = new DependencyInjectionTypeRegistrar(services);

            // Create the CommandApp with specified command type and type registrar.
            var app = new CommandApp<DefaultCommand>(registrar);

            // Configure any commands in the application.
            app.Configure(config =>
            {
                config.CaseSensitivity(CaseSensitivity.None);
                config.SetApplicationName("Basic.Cli");
                config.ValidateExamples();

                config.AddCommand<DefaultCommand>("default")
                    .WithDescription("Default command that displays some text.")
                    .WithExample(new[] { "default", "--verbose", "high" });
            });

            return await app.RunAsync(args);
        }
    }
}

Note: these code snippets assume using the Microsoft.Extensions.DependencyInjection framework. But similar sample code also exists for the other DI frameworks.

Samples:

For more detailed examples on how to use D20Tek.Spectre.Console.Extensions, please review the following samples:

  • Basic Cli with DI - full listing for code in the Usage - Custom Code section above.
  • DependencyInjection.Cli - More elaborate use of Microsoft.Extensions.DependencyInjection registrar and resolver. Along with using the CommandAppBuilder to remove some of the creation complexity.
  • Autofac.Cli - Use the Autofac DI framework to build type registrar and resolver.
  • Lamar.Cli - Use the Lamar DI framework to build type registrar and resolver.
  • LightInject.Cli - Use the LightInject DI framework to build type registrar and resolver.
  • Ninject.Cli - Use the Ninject DI framework to build type registrar and resolver.
  • SimpleInjector.Cli - Use the SimpleInjector DI framework to build type registrar and resolver.
  • NoDI.Cli - Use the CommandAppBuilder to configure a console app that does not use a DI framework.
  • InteractivePrompt.Cli - Create an interactive prompt that can run other registered commands while remaining in the prompt.

Testing Infrastructure

This library also provides testing classes that help in building your CommandApp unit tests. Using the CommandAppTestContext allows you to easily configure and run commands in isolation. Here is an example of a simple command unit test written in VSTest (though these test contexts will work in any test framework):

//---------------------------------------------------------------------------------------------------------------------
// Copyright (c) d20Tek.  All rights reserved.
//---------------------------------------------------------------------------------------------------------------------
using D20Tek.Spectre.Console.Extensions.Testing;
using D20Tek.Spectre.Console.Extensions.UnitTests.Mocks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Spectre.Console.Cli;
using System;
using System.Diagnostics.CodeAnalysis;
using System.Threading.Tasks;

namespace D20Tek.Spectre.Console.Extensions.UnitTests.Testing
{
    [TestClass]
    public class CommandAppTestContextTests
    {
        [TestMethod]
        public void Run()
        {
            // arrange
            var context = new CommandAppTestContext();
            context.Configure(config =>
            {
                config.Settings.ApplicationName = "Run Test 1";
                config.AddCommand<MockCommand>("test");
            });

            // act
            var result = context.Run(new string[] { "test" });

            // assert
            Assert.IsNotNull(result);
            Assert.AreEqual(0, result.ExitCode);
            StringAssert.Contains(result.Output, "Success");
            Assert.AreEqual("test", result.Context.Name);
            Assert.IsInstanceOfType(result.Settings, typeof(EmptyCommandSettings));
        }
    }
}

Feedback

If you use these libraries and have any feedback, bugs, or suggestions, please file them in the Issues section of this repository.

Product Compatible and additional computed target framework versions.
.NET net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.50.1.7 113 7/31/2025
1.50.1.6 99 7/28/2025
1.50.1.5 144 7/1/2025
1.50.1.4 77 6/21/2025
1.50.1.3 270 6/9/2025
1.50.1.2 88 6/7/2025
1.50.1 142 6/5/2025

Split off additional dependency injection containers into this package to minimize dependencies in the core package.