
- •Table of Contents
- •About the Author
- •Acknowledgments
- •Introduction
- •Version Support
- •Supported Versions
- •A Unified Platform
- •Roadmap
- •Supported Operating Systems
- •Command Line Interface
- •Desktop Development
- •Blazor
- •MAUI
- •Wrapping Up
- •.NET 6 Architecture
- •Runtimes
- •CoreCLR
- •Mono
- •WinRT
- •Managed Execution Process
- •Desktop Packs
- •Wrapping Up
- •Dotnet New
- •Dotnet Restore
- •NuGet.config
- •Dotnet Build
- •Dotnet Publish
- •Dotnet Run
- •Dotnet Test
- •Using the CLI in GitHub Actions
- •Other Commands
- •Wrapping Up
- •WinAPI
- •WinForms
- •STAThread
- •WinForms Startup
- •DPI Mode
- •Responding to Scale Events
- •Visual Styles
- •Text Rendering
- •The Message Loop
- •The Form Designer
- •WPF Startup
- •XAML Layout
- •Visual Tree
- •Data Binding
- •Windows App SDK
- •Building a Windows App SDK application
- •Using Windows APIs with Windows App SDK
- •Packaging
- •Migrating to .NET 6
- •Upgrade Assistant
- •Wrapping Up
- •Blazor WebAssembly
- •Creating a Blazor Wasm Project
- •Blazor Progressive Web Apps
- •Exploring the Blazor Client Project
- •Blazor in .NET 6
- •Blazor Component System
- •Creating Blazor Pages
- •Running a Blazor App
- •Blazor Server
- •SignalR
- •Blazor Desktop
- •Wrapping Up
- •Project Structure
- •Exploring MAUI
- •The Cross-Platform World
- •Application Lifecycle
- •MVVM
- •MVVM Toolkit
- •Wrapping Up
- •Model-View-Controller
- •Routing
- •Views
- •Controllers
- •Controller-Based APIs
- •Minimal APIs
- •Wrapping Up
- •Web Apps
- •Creating an App Service
- •Static Web Apps
- •Web App for Containers
- •Docker
- •Azure Functions
- •Deploying Azure Functions
- •Wrapping Up
- •Record Types
- •Monolith Architecture
- •Microservices
- •Container Orchestration
- •Kubernetes
- •Docker Compose
- •Dapr
- •Installing Dapr
- •Dapr State Management
- •Wrapping Up
- •Roslyn
- •Compiler API
- •Diagnostic API
- •Scripting API
- •Workspace API
- •Syntax Tree
- •Roslyn SDK
- •Source Generators
- •Writing a Source Generator
- •Debugging Source Generators
- •Wrapping Up
- •Garbage Collector
- •The Heap
- •The Stack
- •Garbage Collection
- •A Look at the Threadpool
- •Async in .NET 6
- •Await/Async
- •Cancellations
- •WaitAsync
- •Conclusion
- •Index

Chapter 3 Command Line Interface
Since the templates have been installed on my machine, dotnet new knows what to do. It inflates the template into a new project and puts it in the directory my command line is currently set in. the -o parameter stands for Output; dotnet new will use this as the name for both the folder and the project it’s creating.
Templates are distributed using NuGet infrastructure and thus are packaged as NuGet packages. The default install location of these templates on Windows is
%USERPROFILE%\.templateengine\dotnetcli\.
An interesting option in dotnet new is the dry-run option. Figure 3-4 shows the output if we try to create a new WPF project with the --dry-run flag.
Figure 3-5. Dry-run output
Dry-run lists all the actions that would have happened if the command was run without --dry-run. It didn’t actually do anything; the command just lists what would have happened.
Creating new projects through inflating a template is handled by a component called the .NET Core Templating Engine. It’s an open source piece of software, available at https://github.com/dotnet/templating.
Dotnet Restore
The dotnet restore command restores dependencies and tools of a project. It uses the information in the project’s projectfile (*.csproj in case of a C#-based project). This command usually does not need to be executed explicitly; it gets triggered from the following:
38
|
Chapter 3 Command Line Interface |
•\ |
dotnet new |
•\ |
dotnet build |
•\ |
dotnet build server |
•\ |
dotnet run |
•\ |
dotnet test |
•\ |
dotnet publish |
•\ |
dotnet pack |
Should you still want to do dotnet restore manually for whatever reason, you can stop it being called from the above commands by using the --no-restore option like so:
Listing 3-3. Creating a new project without restoring packages dotnet new wpf -o WpfDemo --no-restore
Being able to prevent package restore and call it whenever we need it gives us the flexibility needed to setup a fine-grained build pipeline. More on build and release pipelines further in this chapter.
Listing 3-4 shows the help on dotnet restore.
Listing 3-4. dotnet restore help
Usage:
dotnet [options] restore [<PROJECT | SOLUTION>...]
Arguments:
<PROJECT | SOLUTION> The project or solution file to operate on. If a file is not specified, the command will search the current directory for one.
Options: |
|
-s, --source <SOURCE> |
The NuGet package source to use for |
|
the restore. |
--packages <PACKAGES_DIR> |
The directory to restore packages to. |
--use-current-runtime |
Use current runtime as the target |
|
runtime. |
--disable-parallel |
Prevent restoring multiple projects |
|
in parallel. |
39
Chapter 3 Command Line Interface |
|
--configfile <FILE> |
The NuGet configuration file to use. |
--no-cache |
Do not cache packages and http |
|
requests. |
--ignore-failed-sources |
Treat package source failures as |
|
warnings. |
-f, --force |
Force all dependencies to be resolved |
|
even if the last restore was |
|
successful. |
|
This is equivalent to deleting |
|
project.assets.json. |
-r, --runtime <RUNTIME_IDENTIFIER> |
The target runtime to restore |
|
packages for. |
--no-dependencies |
Do not restore project-to-project |
|
references and only restore the |
|
specified project. |
-v, --verbosity <LEVEL> |
Set the MSBuild verbosity level. |
|
Allowed values are q[uiet], |
|
m[inimal], n[ormal], d[etailed], and |
|
diag[nostic]. |
--interactive |
Allows the command to stop and wait |
|
for user input or action (e.g., to |
|
complete authentication). |
--use-lock-file |
Enables project lock file to be |
|
generated and used with restore. |
--locked-mode |
Don't allow updating project |
|
lock file. |
--lock-file-path <LOCK_FILE_PATH> |
Output location where project lock |
|
file is written. By default, this is |
|
'PROJECT_ROOT\packages.lock.json'. |
--force-evaluate |
Forces restore to reevaluate all |
|
dependencies even if a lock file |
|
already exists. |
-?, -h, --help |
Show command line help. |
40
Chapter 3 Command Line Interface
Dotnet restore needs a project to restore; it either finds this implicitly in the folder the command line is currently set in, through a project path can be passed explicitly or through a solution file.
Before we can build an application, we first need to do a dotnet restore. This will generate a project.assets.json file that dotnet build needs. That file contains a complete configuration for dotnet build; it configures project path and name, referenced libraries, target frameworks, and so on. Listing 3-5 shows an example of the project.assets.json.
Listing 3-5. project.assets.json example
{
"version": 3, "targets": { "net6.0": {}
},
"libraries": {}, "projectFileDependencyGroups": {
"net6.0": []
}, "packageFolders": {
"C:\\Users\\myUser\\.nuget\\packages\\": {},
"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\ NuGetPackages": {},
"C:\\Program Files (x86)\\Microsoft\\Xamarin\\NuGet\\": {}, "C:\\Program Files\\dotnet\\sdk\\NuGetFallbackFolder": {}
}, "project": {
"version": "1.0.0", "restore": {
"projectUniqueName": "C:\\Projects\\Apress\\cli\\CliDemo\\CliDemo. csproj",
"projectName": "CliDemo",
"projectPath": "C:\\Projects\\Apress\\cli\\CliDemo\\CliDemo.csproj", "packagesPath": "C:\\Users\\myUser\\.nuget\\packages\\", "outputPath": "C:\\Projects\\Apress\\cli\\CliDemo\\obj\\", "projectStyle": "PackageReference",
41
Chapter 3 Command Line Interface
"fallbackFolders": [
"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\ NuGetPackages",
"C:\\Program Files (x86)\\Microsoft\\Xamarin\\NuGet\\", "C:\\Program Files\\dotnet\\sdk\\NuGetFallbackFolder"
], "configFilePaths": [
"C:\\Users\\myUser\\AppData\\Roaming\\NuGet\\NuGet.Config", "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio. FallbackLocation.config",
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio. Offline.config",
"C:\\Program Files (x86)\\NuGet\\Config\\Xamarin.Offline.config"
], "originalTargetFrameworks": [
"net6.0"
], "sources": {
"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {}, "https://api.nuget.org/v3/index.json": {}
}, "frameworks": {
"net6.0": { "targetAlias": "net6.0", "projectReferences": {}
}
}, "warningProperties": {
"warnAsError": [ "NU1605"
]
}
}, "frameworks": {
"net6.0": { "targetAlias": "net6.0",
42