The best C# REPL is in your terminal

Read-Eval-Print-Loop (REPL) is an interactive program that reads your input, evaluates it, prints the result, and loops back to the beginning. It’s a great way to experiment with a programming language and an excellent method for learning a new language. C# has many REPLs; some are web-based, others are desktop applications, and some are command-line tools. There’s .NET FiddleTry .NET, the popular LINQPad, the built-in csi.exe, and many more.

But there’s one C# REPL that I find above all others. It runs in your terminal, is easy to install, and easy to use. The included Intellisense, documentation and suggested overloads increases productivity. It supports theming, and when I use this REPL, I almost feel like I’m coding in a regular IDE. I always have a terminal open, so it’s very convenient to have such an advanced C# REPL in it, available in a few keystrokes.

The C# REPL I’m talking about is simply called… C# REPL. It’s an open-source project created by Will Fuqua, and as of today, it has over 2k GitHub stars. It is distributed as a .NET tool and is cross-platform. In this blog post, I’m going to show you how to install it on Windows Terminal, but you can install it on any terminal emulator you prefer.

Continue reading “The best C# REPL is in your terminal”

Convert complex YAML to .NET types with custom YamlDotNet type converters

When it comes to YAML serialization and deserialization in .NET, YamlDotNet is a go-to library with over 100 million downloads on NuGet. It is also integrated into various projects by Microsoft and the .NET team, despite the absence of an official Microsoft YAML library for .NET.

In this blog post, we will explore the process of creating custom YAML serializers and deserializers using YamlDotNet. To illustrate these concepts, we’ll examine the specific use case of partially parsing the environment variables section of a Docker Compose file.

Continue reading “Convert complex YAML to .NET types with custom YamlDotNet type converters”

Instrumenting System.CommandLine-based .NET applications

In our previous posts, we’ve learned how to build beautiful command-line applications using System.CommandLine and modern dependency injection. There might be situations where you want to monitor how your application is used. The specifics of what telemetry data to gather will largely depend on your application’s nature. Remember, it’s not appropriate to collect personally identifiable information (PII) in publicly available apps, although it might be acceptable if you’re creating an internal tool for your company.

This blog post will guide you on how to – one more time – build on top of System.CommandLine to track usage, understand your application’s behavior, and gather valuable data. This might include the duration of the command execution, user information, command arguments, and more.

Continue reading “Instrumenting System.CommandLine-based .NET applications”

Crafting beautiful interactive console apps with System.CommandLine and Spectre.Console

In our last talk about System.CommandLine, we learned how to easily build command line apps using .NET and C#, following most of the advice from CLI guidelines. We also brought in dependency injection to make our code more flexible, easier to read, and simpler to test.

Now that we have our basic setup ready, it’s time to improve our user experience. So far, users have been interacting with our app by typing every single argument each time they invoke the app. In this next part of my System.CommandLine journey, we’re going to make our CLI apps beautiful but also interactive, thanks to the Spectre.Console .NET library.

Continue reading “Crafting beautiful interactive console apps with System.CommandLine and Spectre.Console”

How to configure true dependency injection in System.CommandLine

System.CommandLine is the official .NET library that provides common functionality for command-line applications. This includes features like argument parsing, automatic help text generation, tab autocomplete, suggestions, corrections, sub-commands, user cancellation, and much more. Many official .NET tools are built on top of System.CommandLine, including the .NET CLIKiotaTye, some Azure tools, and other .NET additional tools.

Despite the fact that the library has been in preview for several years, its use in numerous .NET CLI programs inspires confidence regarding its maturity. The public C# API, though not final, is intuitive, the documentation is okay, and many examples and tests in the GitHub repository can assist you in getting started.

However, there is one aspect of System.CommandLine that I dislike: its lack of built-in support for dependency injection, like in any good modern .NET application. It makes it quite difficult to unit test and introduce decoupling in general.

To be fair, a service provider is indeed present within System.CommandLine. This provider implements IServiceProvider and can be accessed through the InvocationContext.BindingContext.ServiceProvider property. But upon closer inspection, you’ll notice that this is not your typical, modern, fully-featured service provider. In fact, it’s a pseudo service provider backed by a simple dictionary of factories (Dictionary<Type, Func<IServiceProvider, object?>>). Its functionality is severely limited, and it’s not exactly user-friendly when it comes to service registration. Don’t take my word for it, make your own idea by reading the documentation.

Fortunately, System.CommandLine (in its current version, 2.0.0-beta4.22272.1) is highly extensible. In this blog post, I’ll show you how to integrate true dependency injection using the official Microsoft.Extensions.DependencyInjection NuGet package.

Continue reading “How to configure true dependency injection in System.CommandLine”