28,79 €
Developers and system administrators often face challenges like inefficient workflows, complex system operations, and the growing demand for robust automation tools. CLI applications provide a powerful solution by enhancing flexibility, efficiency, and productivity in various environments. This book will guide you through mastering the development of robust command-line tools using .NET.
Written by a Microsoft Azure MVP, the book’s hands-on approach ensures practical experience with real-world projects. You’ll start with an overview of foundational principles, essential concepts, and best practices for CLI application development. From there, you’ll advance to creating interactive interfaces, integrating with external APIs and services, and implementing security measures to safeguard your applications. Each chapter will build progressively from basic to advanced topics.
Beyond development, you’ll learn how to enhance application quality through testing, package for efficient distribution, and deploy effectively. The book also teaches strategies to optimize performance to ensure your applications run efficiently under heavy usage.
By the end of this book, you’ll have gained a deep understanding of CLI application development with .NET to build modular, extensible, and easy-to-maintain applications.
Das E-Book können Sie in Legimi-Apps oder einer beliebigen App lesen, die das folgende Format unterstützen:
Seitenzahl: 325
Veröffentlichungsjahr: 2025
Building CLI Applications with C# and .NET
Foreword
Contributors
About the author
About the reviewer
Learn more on Discord
Preface
Who this book is for
What this book covers
To get the most out of this book
Download the example code files
Conventions used
Get in touch
Share Your Thoughts
Free Benefits with Your Book
Part 1: Getting Started with CLI Applications
Chapter 1: Introduction to CLI Applications
A day in the life of an IT professional
Why care about CLI applications?
To CLI or not to CLI?
CLI applications as the building block for creating workstation profiles
Even heavy graphical applications have a CLI tool!
Even ChatGPT has a CLI!
Summary
Chapter 2: Setting Up the Development Environment
Technical requirements
Installing Visual Studio Code
Installing the required extensions
Installing the .NET SDK
Installing and configuring Git
Summary
Your turn!
Chapter 3: Basic Concepts of Console Applications in .NET
Technical requirements
Creating (and executing) a simple console application
Working with the System.Console class
Useful properties
Useful methods
Useful event
One more thing
Summary
Your turn!
Part 2: Foundations of Building CLI Applications
Chapter 4: Command-Line Parsing
Technical requirements
Creating the console application
Parsing the arguments of a console application
From console to CLI – parsing the arguments using an existing library
Adding the root command
Adding the link command
About commands
Do all commands need to have a handler method?
Adding options to the link command
What other types of options can we use?
Getting help
Getting the application’s version number
Summary
Your turn!
Task #1 – Delete an existing bookmark
Task #2 – Update an existing bookmark
Task #3 – List all existing bookmarks
Chapter 5: Input/Output and File Handling
Technical requirements
Controlling input values for an option
Required versus non-required options
What about arguments?
Setting a default value for an option
Controlling the allowed values for an option
Validating input values
Adding multiple elements in one go
Working with files passed in as options values
Summary
Your turn!
Task #1 – validating the format and the ability to access the input file
Task #2 – merging existing links from the input file
Chapter 6: Error Handling and Logging
Technical requirements
Handling errors in CLI applications
Handling exceptions
Handling errors doesn’t necessarily mean handling exceptions
Handling program termination
Logging in CLI applications
Why JSON?
Why Serilog?
Accessing IServiceCollection
Adding Serilog to IServiceCollection
Adding (and configuring) the required Serilog sinks
Configuring sinks in appsettings.json
Let’s log something!
Closing and gracefully disposing of Serilog
Summary
Your turn!
Task #1 – Handling errors for the Import command
Task #2 – Logging errors to a file
Part 3: Advanced Topics in CLI Application Development
Chapter 7: Interactive CLI Applications
Technical requirements
Building interactive command-line applications
Adding a FIGlet
Designing user-friendly CLI applications
Enhancing text display using markup
Offering choices to the user using selection prompts
Showing live progress of the export command
Displaying bookmarks in a tree view
To be or not to be interactive?
Summary
Your turn!
Task 1 – present a bookmark in a user-friendly way
Task 2 – change the category of a bookmark interactively
Chapter 8: Building Modular and Extensible CLI Applications
Technical requirements
Step 1 – building a code map of the application
Using the Help menu to build the code map
Step 2 – deciding where to start
Step 3 – designing the project structure
Step 4 – refactoring the export command
Step 5 – applying the dependency inversion principle
Step 6 – refactoring the Program class
Step 7 – running the program
Taking refactoring to new heights
Updating the project structure
Summary
Your turn!
Task #1 – refactor the remaining commands
Chapter 9: Working with External APIs and Services
Technical requirements
Why consume external APIs?
How to consume an external API
Benefits of using IHttpClientFactory
Bookmarkr: your bookmarks, anywhere!
The sync command
Registering the sync command
Running the program
Reducing the coupling between our application and the external dependency
About the Service Agent pattern
Implementing the Service Agent pattern
Rerunning the program
Summary
Your turn!
Task #1 – adding SQLite as a data store
Task #2 – retrieving the web page name based on its URL
Part 4: Testing and Deployment
Chapter 10: Testing CLI Applications
Technical requirements
Why is testing so important?
Types of tests
About usability tests
The pyramid of (software) testing
What should we test?
What not to test
Testing is a safety net
When should we run tests?
Adding a test project to Bookmarkr
Structuring the test project
Code artifacts that should not be tested
Writing effective tests
Running our tests
Mocking external dependencies
The role of mocking
How to mock an external dependency
Mocking the BookmarkService service
Using the mock version of the BookmarkService service
Changes to the code must be made!
Going back to implementing the test cases
Internals visibility
Centralizing test initialization
How to hunt a bug
Summary
Your turn!
Task #1 – Write the required unit tests for the remaining functionalities
Task #2 – Write integration tests for the sync command
Chapter 11: Packaging and Deployment
Technical requirements
A bit of terminology
Packaging and distribution options for CLI applications
Packaging and distributing a CLI application
Option #1 – as a .NET tool
Option #2 – as a Docker container
Option #3 – as a WinGet package
Managing versions of the application
Semantic versioning primer
Managing versions of a .NET tool
Managing versions of a Docker container
Managing versions of a WinGet package
Summary
Your turn!
Task #1 – allowing Linux users to install Bookmarkr using apt-get
Task #2 – allowing macOS users to install Bookmarkr using Homebrew
Part 5: Advanced Techniques and Best Practices
Chapter 12: Performance Optimization and Tuning
Technical requirements
Performance optimization areas
Instrumenting .NET applications
Hot spots versus hot paths
Identifying the application’s hot spots and hot paths
Profiling Bookmarkr with BenchmarkDotNet
Monitoring BookmarkrSyncr with Azure Application Insights
Common performance optimization techniques
Optimizing Bookmarkr’s performance
Summary
Your turn!
Task #1 – Write more benchmarks
Task #2 – Fine-tune Bookmarkr for optimal performance
Chapter 13: Security Considerations for CLI Applications
Technical requirements
Security areas
Assessing the security posture of a CLI application
Securing remote communications using authentication
Why is authentication important?
How to perform authentication
Implementing authentication
Authenticating external services using a PAT
Passing the PAT from the CLI application to the external service
Summary
Your turn!
Task #1 – Update dependency versions
Task #2 – Use Mend Bolt to scan the code for vulnerabilities
Task #3 – Allow BookmarkrSyncr to manage multiple users
Chapter 14: Additional Resources and Libraries
Further reading and resources
C# 12 and .NET 8, by Mark J. Price
Refactoring with C#, by Matt Eland
Pragmatic Test-Driven Development in C# and .NET, by Adam Tibi
C# 7 and .NET Core 2.0 High Performance, by Ovais Mehboob Ahmed Khan
Useful libraries for CLI application development
Polly
HangFire
StackExchange.Redis
MediatR
MassTransit
BenchmarkDotNet
Portable.BouncyCastle
NSubstitute
AutoFixture
RichardSzalay.MockHttp
Summary
Your turn!
Task #1 – List additional features for Bookmarkr
Task #2 – List the skills and libraries you need to implement a feature
Chapter 15: Unlock Your Exclusive Benefits
Unlock this Book’s Free Benefits in 3 Easy Steps
Step 1
Index
Why subscribe?
Other Books You May Enjoy
Packt is searching for authors like you
Share Your Thoughts
Cover
Table of Contents
Index
Building CLI Applications with C# and .NET
A step-by-step guide to developing cross-platform CLI apps—from coding and testing to deployment
Tidjani Belmansour
Copyright © 2025 Packt Publishing
All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews.
The author acknowledges the use of cutting-edge AI, such as ChatGPT, with the sole aim of enhancing the language and clarity within the book, thereby ensuring a smooth reading experience for readers. It’s important to note that the content itself has been crafted by the author and edited by a professional publishing team.
Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the author, nor Packt Publishing or its dealers and distributors, will be held liable for any damages caused or alleged to have been caused directly or indirectly by this book.
Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.
Group Product Manager: Kunal Sawant
Publishing Product Manager: Samriddhi Murarka
Book Project Manager: Prajakta Naik
Lead Editor: Kinnari Chohan
Technical Editor: Vidhisha Patidar
Copy Editor: Safis Editing
Proofreader: Kinnari Chohan
Indexer: Tejal Soni
Production Designer: Alishon Mendonca
Senior DevRel Marketing Executive: Sonia Chauhan
First published: February 2025
Production reference: 3071125
Published by Packt Publishing Ltd.
Grosvenor House
11 St Paul’s Square
Birmingham
B3 1RB, UK.
ISBN 978-1-83588-274-0
www.packtpub.com
To my wife Lamia Rarrbo and to my daughter Camélia, for being the sunshine of my life. To my family for your love and support.
– Tidjani Belmansour
I remember when I first used Git.
I’d spent years working with Team Foundation Server (using TFVC), and I’d always done so through Visual Studio, so I’d become very used to the GUI. But Git felt like a different animal. I resolved to learn to use it from the Windows command line rather than relying on pointing and clicking.
It turned out to be a great decision. The CLI felt powerful and raw and exposed me to more of how Git worked. The simple request-response pattern was natural, and each command was self-contained. It meant that later, when I used GUI tools such as GitHub Desktop, I still understood what was happening under the hood. In subsequent jobs, no matter how unfamiliar the operating system, IDE, or development environment was, it always felt like I could drop back to the terminal to “talk to Git directly.”
Git was my gateway tool, but I quickly learned to love the simplicity of a CLI. It was straightforward when it needed to be, but for more power, I learned how to chain commands together or to use tools such as jq to parse JSON responses. For integration with my own software or scripts, well-written CLI tools meant I could make requests of APIs without having to construct exactly the right HTTP headers (is it text/jsonor application/json?).
When my career moved increasingly toward DevOps and developer processes, CLI tools became a core part of my practice, particularly when constructing CI/CD pipelines. It didn’t matter what tool I was using; it was easy to call a CLI tool to get the job done. CLIs were often cross-platform and consistent regardless of where you executed them. Switching from Jenkins to Azure Pipelines to GitHub Actions was not a big deal. It involved the same commands – they were just called from a different orchestrator.
Over time, I’ve come to love CLI tools for their simplicity, power, and directness. It brings me great joy when I see a CLI option alongside an API or GUI. It’s just another way to work with the software I use every day.
Applications and websites are frequently written with beautiful user interfaces, and these interfaces are important. But I think we’d be well served if more developers thought about – and built – the CLI as a first-class interface.
Damian Brady
Staff Developer Advocate, GitHub
Formerly DevOps Advocate at Microsoft
Tidjani Belmansour is an expert in developing and architecting solutions on the Microsoft Azure platform, particularly in .NET, with over 21 years of experience. His passion for development began early—he wrote his first program in QuickBasic at the age of eight and has never stopped since. He is currently the Director of the Azure Centre of Excellence at Cofomo, where he collaborates with organizations of all sizes, across both public and private sectors, and on projects around the globe.
Since 2019, Tidjani has been recognized as a Microsoft Azure MVP. He is also the co-host of the Azure Quebec Community, a trainer, a blogger, and an international speaker. Tidjani holds a BSc in Computer Science and a Ph.D. in Engineering.
This book is dedicated to my wife, Lamia, and my daughter, Camélia, for bringing light into my life and for being my source of support and inspiration. I love you both more than words can express.
To my family: my mother, Fatiha; my sister, Lamia; my second mom, Nacera; my sisters-in-law, Assia and Meriem; my brothers-in-law, Karim and Jordan; and my nephews, Zaki and Yani.
And to the memory of my father, Omar; my second father, Nasseradine; and my brother, Mounir.
Mabrouk Mahdhi is a software engineer, Microsoft MVP, and the founder of CodeCampsis, a consulting firm specializing in innovative IT solutions and .NET technologies. With a passion for technology and a commitment to sharing knowledge, Mabrouk is also a book author and an accomplished speaker, inspiring and educating audiences on a global scale.
To join the Discord community for this book – where you can share feedback, ask questions to the author, and learn about new releases – follow the QR code below:
https://packt.link/BuildNETCLI
In this part, you will get an overview of command-line interface (CLI) applications and understand their importance in modern software development. In addition, you will learn about setting up an efficient development environment for CLI programming, including essential tools and frameworks. Finally, you will explore the basic concepts of console applications in .NET, providing you with a solid foundation for creating powerful CLI tools.
This part has the following chapters:
Chapter 1, Introduction to CLI ApplicationsChapter 2, Setting Up the Development EnvironmentChapter 3, Basic Concepts of Console Applications in .NETIn the realm of computing, command-line interface (CLI) applications exemplify the enduring power and efficiency of text-based user interfaces. Unlike their graphical counterparts, CLI applications offer a streamlined, no-frills approach to interacting with software, allowing users to execute commands, manipulate files, and perform a myriad of tasks right from the terminal, or automate them so these tasks do not require user interaction at all!
In this chapter, we will cover the following topics:
An IT professional’s typical dayWhat CLI applications are, what their benefits are, and when to use themPopular CLI applicationsFree Benefits with Your Book
Your purchase includes a free PDF copy of this book along with other exclusive benefits. Check the Free Benefits with Your Book section in the Preface to unlock them instantly and maximize your learning experience.
It’s a beautiful Monday morning. Today, my team and I are starting a new project.
The project is to build a web application using ASP.NET with Entity Framework as an object-relational mapper (ORM), NuGet for managing dependencies, Git as a code versioning system, and, since the application is to be deployed on Azure, Bicep as an infrastructure scripting language.
A few years ago, I would have used GUI applications for this, such as the full-fledged Visual Studio, GitHub Desktop, or GitKraken, and the Azure portal.
Today, I doing most of my work in Visual Studio Code and its integrated terminal.
So, I use commands such as mkdir to create my project directory, cd to position myself into this directory, dotnet new to create my project, git init to initialize the Git repository, dotnet add package to add NuGet packages as dependencies to my project, dotnet ef dbcontext scaffold to generate a database context and all the entity type classes for my database, dotnet build to compile my application, and dotnet run to run it. When comes the time to deploy my application to Azure, I use commands such as az login to log into my Azure account, az account set to position myself onto the appropriate subscription, and finally, az deployment group create to deploy my Azure infrastructure as declared in my Bicep script.
When I realized that, I paused to pay careful attention to the situation. Wow, CLI applications are everywhere! They are truly part of our daily operations, no matter the role we play in an IT team.
I wondered how I missed that… then it hit me. This might be because CLI applications are a bit shy (they have no flashy UIs), and for that reason, we may not always notice them, so let me tell you about some common ones:
If you are a developer, you have certainly used the .NET CLI (dotnet), the Node.js CLI (node), the npm package manager (npm), the Angular CLI (ng), Python (python), Git (git), Docker (docker), Kubernetes (kubectl), and many more.If you are a DevOps engineer, you may be using Git (git), GitHub (gh), Azure DevOps (azdevops), Docker (docker), Kubernetes (kubectl), Ansible (ansible), and so on.If you are a system administrator, you may be regularly using package managers on various operating systems, such as apt on Linux, brew on macOS, or even choco or winget on Windows. You also most likely use shells, automation, and configuration tools such as PowerShell or Bash.If you are a cloud administrator or architect, you may be using the Azure CLI (az), the AWS CLI (aws), Terraform (terraform), or Bicep (bicep), among others.If you are a data scientist, you might be using Python (python), R (R), Pandas (pandas), SQL (sql), or Jupyter Notebooks (jupyter notebook).If you are a video or audio producer, a content creator, or simply a multimedia enthusiast, you are probably using FFmpeg (yes, it is a CLI application) to manipulate, convert, and analyze media files.And the list goes on and on…Then, I started wondering why this happened. How come we switched from those beautiful UIs with their shiny colors and animations, inviting us to do all sorts of tasks and activities, to the blinking cursor inside of that terminal that is waiting for us to tell it what to do? This might seem like a big leap backward, right?
I know I struggled with that feeling until I figured out why CLI applications are so great! Sure, they make us look cool and smart in front of our Muggle friends and relatives. But it’s not about that. Okay… not only about that. Because, when we are alone working on our project, there are not many people to impress.
So…
Because they improve our productivity by keeping us focused on the task at hand.
You see, when we switch contexts between different applications, the chances are that we lose sight of what we were doing and get derailed from our task by some other unrelated activity.
By relying on CLI applications, all the commands that we type and execute happen to be within the same terminal, so we have a better chance of staying focused on what we are doing, thus achieving more.
That is the question. And the answer is quite simple: you don’t have to choose. In some scenarios, CLI applications make perfect sense, while in others they make no sense. Imagine using Microsoft Teams, Slack, or any tool of the Adobe Creative Suite. Would it make sense to interact with these applications as CLI applications? Of course not! (unless it is for installing and configuring them).
So, the point here is that you become aware of the power of CLI applications, and you start taking advantage of them in your everyday workflow. They are not meant to replace those outstanding GUI applications.
As my wife, Lamia Rarrbo (who is an executive coach) says: “This is not an or situation but rather an and situation.”
Let me tell you a true story. A few years ago, one of my customers asked me to come up with a solution to build workstation configuration profiles for different roles within their company.
This is nothing new, you may say, and you are exactly right!
So, what makes this situation worth mentioning? What makes it special?
For many years, this used to be achieved using customized OS images, depending on the role you have in the organization. However, this comes at a cost:
The cost of storage: These images tend to be large and hence require a lot of disk space to store them.The cost of OS updates: When a new OS version is introduced, the IT department must recreate all images.The cost of tools updates: When new versions of the tools utilized by the various profiles are introduced, the IT department must recreate the impacted images.The cost of frustration: Since computers are configured using these images, and because this activity is solely performed by the IT department, it causes frustrations at both ends. First, users accuse the IT department of being slow at providing them with their new machine (“3 weeks to configure a new laptop?! You gotta be kidding me!”. We have all heard this at some point, right?). Second, the IT people have to configure these computers in addition to their other tasks.The solution I proposed is to leverage CLI applications to provide users with more autonomy while ensuring that the IT department still has control over what is deployed on the workstations.
So, I built configuration profiles for each role as a PowerShell script. This script relies on Chocolatey (and, later, on WinGet) to install all the necessary tools for a given user role. These scripts were stored on a file share that users had access to according to their role (so, for example, if you are an analyst, you don’t have access to the developer profile, and so on).
This solution provided multiple advantages:
The IT department now only installs the OS, configures the user account, and hand the workstation to the userThe user can now navigate to the file share and start the installation of their software based on their profileThe IT department can update the configuration profiles, or provide new ones, without having an impact on the users and without making them waitHence, by leveraging CLI tools, we were able to automate workstation configuration in a personalized manner, according to users’ profiles. Imagine how tedious this would have been if we had to install each and every application through its GUI assistant!
By relying on CLI tools, we were able to improve both the IT department’s productivity and users’ satisfaction.
Why is the preceding story interesting?
It’s not because of the use of PowerShell, WinGet, or Chocolatey. These are clearly CLI tools.
It is because we designed a way to install software from the command line without involving any GUI. This means that even if we are installing graphical applications (such as the Microsoft Office suite, internet browsers, and the Adobe suite), we are doing so by relying on their own CLI tools.
Yes, these graphical applications provide a CLI tool allowing us to install (and sometimes also configure) these applications.
