Monbsoft.CliCoreKit.Hosting
1.2.1
See the version list below for details.
dotnet add package Monbsoft.CliCoreKit.Hosting --version 1.2.1
NuGet\Install-Package Monbsoft.CliCoreKit.Hosting -Version 1.2.1
<PackageReference Include="Monbsoft.CliCoreKit.Hosting" Version="1.2.1" />
<PackageVersion Include="Monbsoft.CliCoreKit.Hosting" Version="1.2.1" />
<PackageReference Include="Monbsoft.CliCoreKit.Hosting" />
paket add Monbsoft.CliCoreKit.Hosting --version 1.2.1
#r "nuget: Monbsoft.CliCoreKit.Hosting, 1.2.1"
#:package Monbsoft.CliCoreKit.Hosting@1.2.1
#addin nuget:?package=Monbsoft.CliCoreKit.Hosting&version=1.2.1
#tool nuget:?package=Monbsoft.CliCoreKit.Hosting&version=1.2.1
CliCoreKit
A powerful and flexible command-line parsing library for .NET 10 with full integration with Microsoft.Extensions.Hosting, dependency injection, and middleware pipeline support.
Features
- Modern .NET 10 - Built for the latest .NET platform
- Multiple Parsing Styles - Supports POSIX (
-v), GNU (--verbose), and Windows (/v) style arguments - Hierarchical Commands - Create nested subcommands like
git remote add - IHostBuilder Integration - Seamless integration with .NET Generic Host
- Dependency Injection - Full DI support for commands and services
- Middleware Pipeline - Extensible middleware system following Open/Closed Principle (SOLID)
- Type-Safe Parsing - Strongly-typed argument parsing with validation
- Fluent API - Clean and intuitive configuration syntax
Architecture
graph TB
A[CliCoreKit.Core] -->|Provides| B[Command Parsing]
A -->|Provides| C[Command Routing]
A -->|Provides| D[Middleware Pipeline]
E[CliCoreKit.Hosting] -->|Extends| F[IHostBuilder]
E -->|Uses| A
G[Your CLI App] -->|References| E
G -->|Uses| H[Microsoft.Extensions.Hosting]
Installation
dotnet add package Monbsoft.CliCoreKit.Core
dotnet add package Monbsoft.CliCoreKit.Hosting
Quick Start
1. Create a Simple Command
using Monbsoft.CliCoreKit.Core;
public class GreetCommand : ICommand
{
public Task<int> ExecuteAsync(CommandContext context, CancellationToken cancellationToken = default)
{
var name = context.GetOptionValue("name") ?? "World";
Console.WriteLine($"Hello, {name}!");
return Task.FromResult(0);
}
}
2. Configure Your CLI Application
using Microsoft.Extensions.Hosting;
using Monbsoft.CliCoreKit.Hosting;
var host = Host.CreateDefaultBuilder(args)
.ConfigureCli(cli =>
{
cli.AddCommand<GreetCommand>("greet", "Greet a user")
.UseValidation();
})
.Build();
return await host.RunCliAsync(args);
3. Run Your Application
dotnet run -- greet --name John
# Output: Hello, John!
Usage Examples
Command-Line Argument Styles
CliCoreKit supports multiple argument parsing styles:
# POSIX style (short options)
myapp -v -f file.txt
# GNU style (long options)
myapp --verbose --file file.txt
# Windows style
myapp /verbose /file file.txt
# Combined short options
myapp -vrf file.txt # Equivalent to -v -r -f file.txt
# Long option with equals
myapp --file=file.txt
# Mixed styles
myapp --verbose -o output.txt file1.txt file2.txt
Hierarchical Subcommands
Create complex command structures like git:
host.ConfigureCli(cli =>
{
// Root command
cli.AddCommand<GitCommand>("git", "Version control system");
// Subcommands
cli.AddSubCommand<CommitCommand>("commit", "git", "Record changes");
cli.AddSubCommand<PushCommand>("push", "git", "Update remote refs");
// Nested subcommands
cli.AddSubCommand<RemoteCommand>("remote", "git", "Manage remotes");
cli.AddSubCommand<RemoteAddCommand>("add", "git.remote", "Add remote");
});
Usage:
myapp git commit -m "Initial commit"
myapp git remote add origin https://github.com/user/repo.git
Dependency Injection
Commands automatically support constructor injection:
public class DataCommand : ICommand
{
private readonly ILogger<DataCommand> _logger;
private readonly IDataService _dataService;
public DataCommand(ILogger<DataCommand> logger, IDataService dataService)
{
_logger = logger;
_dataService = dataService;
}
public async Task<int> ExecuteAsync(CommandContext context, CancellationToken cancellationToken)
{
_logger.LogInformation("Fetching data...");
var data = await _dataService.GetDataAsync(cancellationToken);
Console.WriteLine($"Retrieved {data.Count} items");
return 0;
}
}
Register your services:
var host = Host.CreateDefaultBuilder(args)
.ConfigureServices((context, services) =>
{
services.AddSingleton<IDataService, DataService>();
services.AddLogging();
})
.ConfigureCli(cli =>
{
cli.AddCommand<DataCommand>("data", "Fetch data");
})
.Build();
Middleware Pipeline
Add cross-cutting concerns using middleware:
public class LoggingMiddleware : ICommandMiddleware
{
private readonly ILogger<LoggingMiddleware> _logger;
public LoggingMiddleware(ILogger<LoggingMiddleware> logger)
{
_logger = logger;
}
public async Task<int> InvokeAsync(
CommandContext context,
Func<CommandContext, CancellationToken, Task<int>> next,
CancellationToken cancellationToken = default)
{
_logger.LogInformation("Executing command: {CommandName}", context.CommandName);
var stopwatch = Stopwatch.StartNew();
var result = await next(context, cancellationToken);
stopwatch.Stop();
_logger.LogInformation("Command completed in {ElapsedMs}ms with exit code {ExitCode}",
stopwatch.ElapsedMilliseconds, result);
return result;
}
}
Register middleware:
cli.UseMiddleware<LoggingMiddleware>()
.UseValidation();
Argument Parsing
Access parsed arguments in your commands:
public Task<int> ExecuteAsync(CommandContext context, CancellationToken cancellationToken)
{
// Check if option exists
bool verbose = context.HasOption("verbose") || context.HasOption("v");
// Get option value
string? output = context.GetOptionValue("output");
// Get typed value
if (context.TryGetOption<int>("port", out var port))
{
Console.WriteLine($"Using port: {port}");
}
// Get positional arguments
var file1 = context.GetPositional(0);
var file2 = context.GetPositional(1);
// Get all positional arguments
foreach (var file in context.Positional)
{
Console.WriteLine($"Processing: {file}");
}
return Task.FromResult(0);
}
Advanced Configuration
Custom Argument Parser Options
var parserOptions = new ArgumentParserOptions
{
AllowWindowsStyle = true,
AllowCombinedShortOptions = true
};
var parser = new ArgumentParser(parserOptions);
var router = new CommandRouter(registry, parser);
Command Validation
Define option requirements:
var definition = new CommandDefinition
{
Name = "deploy",
CommandType = typeof(DeployCommand),
Options = new List<OptionDefinition>
{
new()
{
Name = "environment",
ShortName = 'e',
Description = "Target environment",
IsRequired = true,
ValueType = typeof(string)
},
new()
{
Name = "force",
ShortName = 'f',
Description = "Force deployment",
IsRequired = false
}
}
};
Manual Command Registration
For advanced scenarios, you can manually configure commands:
cli.ConfigureCommands((serviceProvider, registry) =>
{
var definition = new CommandDefinition
{
Name = "custom",
Description = "Custom command with complex setup",
CommandType = typeof(CustomCommand),
Options = new List<OptionDefinition>
{
new() { Name = "option1", IsRequired = true }
}
};
registry.Register(definition);
});
Project Structure
CliCoreKit/
├── src/
│ ├── CliCoreKit.Core/ # Core parsing and command infrastructure
│ │ ├── ICommand.cs
│ │ ├── ArgumentParser.cs
│ │ ├── CommandRegistry.cs
│ │ ├── CommandRouter.cs
│ │ ├── Middleware/
│ │ └── Validation/
│ └── CliCoreKit.Hosting/ # IHostBuilder extensions
│ ├── CliHostBuilder.cs
│ ├── HostBuilderExtensions.cs
│ └── CliHostedService.cs
├── tests/
│ ├── CliCoreKit.Core.Tests/
│ └── CliCoreKit.Hosting.Tests/
├── samples/
│ └── CliCoreKit.Sample/ # Example application
└── README.md
Design Principles (SOLID)
This library follows SOLID principles:
- Single Responsibility: Each class has one clear purpose
- Open/Closed: Extensible via middleware without modifying core
- Liskov Substitution: Interface-based design allows substitution
- Interface Segregation: Focused interfaces (ICommand, ICommandMiddleware)
- Dependency Inversion: Depends on abstractions, not concretions
Testing
Run unit tests:
dotnet test
The project includes comprehensive tests for:
- Argument parsing (POSIX, GNU, Windows styles)
- Command registry and routing
- Nested subcommands
- Host builder integration
- Middleware pipeline
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Author
Monbsoft
Acknowledgments
Built with:
- .NET 10
- Microsoft.Extensions.Hosting
- xUnit for testing
- FluentAssertions for test assertions
For more examples, see the samples directory.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. 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. |
-
net10.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Hosting (>= 10.0.0)
- Monbsoft.CliCoreKit.Core (>= 1.2.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.