The dotnet CLI is the primary tool for everything .NET โ creating projects, building, running, testing, publishing, managing packages, and running EF Core migrations. Beyond the basic commands, the CLI supports global tools (executables installed once per user, like dotnet-ef), and project-wide settings via Directory.Build.props and .editorconfig that keep multi-project solutions consistent without repeating configuration in every file. Mastering the CLI accelerates development and is essential for CI/CD pipelines where no IDE is available.
Essential dotnet CLI Commands
// โโ Project creation โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
dotnet new webapi -n BlogApp.Api // ASP.NET Core Web API
dotnet new classlib -n BlogApp.Domain // class library
dotnet new xunit -n BlogApp.Tests // xUnit test project
dotnet new console -n BlogApp.Seeder // console application
dotnet new gitignore // .gitignore for .NET
dotnet new editorconfig // .editorconfig template
dotnet new list // list all available templates
// โโ Building and running โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
dotnet build // build (Debug by default)
dotnet build -c Release // build Release configuration
dotnet run --project src/BlogApp.Api // run the API
dotnet run --project src/BlogApp.Api --watch // hot reload on file changes
// โโ Testing โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
dotnet test // run all tests in solution
dotnet test --filter "Category=Unit" // run tests matching a filter
dotnet test --coverage // collect code coverage
dotnet test -l "console;verbosity=detailed" // verbose output
// โโ Publishing โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
dotnet publish -c Release -o ./publish // publish to ./publish folder
dotnet publish -c Release --self-contained // include .NET runtime
dotnet publish -c Release -r linux-x64 // publish for Linux x64
dotnet run builds the project before running โ it is equivalent to dotnet build followed by running the output binary. For production use, always publish with dotnet publish -c Release and run the published output directly. The published artefact is a self-contained, optimised binary (or folder of DLLs) with all dependencies resolved. Running the development debug build in production is a common mistake that delivers lower performance and includes development-only middleware.dotnet-ef as a global tool for EF Core migrations: dotnet tool install --global dotnet-ef. Then use it throughout development: dotnet ef migrations add InitialCreate --project src/BlogApp.Infrastructure --startup-project src/BlogApp.Api and dotnet ef database update --project src/BlogApp.Infrastructure --startup-project src/BlogApp.Api. The --startup-project flag points to the project that contains the appsettings.json with the connection string; --project points to the project that contains the DbContext and migrations.dotnet watch run (hot reload) is convenient for development but should never be used in production. Hot reload patches the running process with changed code without a restart โ it works for most UI and API changes but has limitations: it does not support all code changes (constructor changes, type additions) and can leave the process in an inconsistent state if a reload fails. Always stop dotnet watch and use a clean dotnet publish + restart cycle for production deployments.Directory.Build.props โ Shared MSBuild Properties
// Directory.Build.props โ place in solution root; applies to ALL projects
// Eliminates repetition of common settings across every .csproj
<!-- Directory.Build.props -->
<Project>
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<LangVersion>latest</LangVersion>
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
<Authors>StackLesson</Authors>
<Company>StackLesson Ltd</Company>
</PropertyGroup>
</Project>
// Individual .csproj files become minimal โ only project-specific settings:
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" />
</ItemGroup>
</Project>
.editorconfig โ Enforcing Code Style
// .editorconfig โ place in solution root; applies to all files
// Controls: indentation, line endings, trailing whitespace, C# naming conventions
[*]
indent_style = space
indent_size = 4
end_of_line = crlf
charset = utf-8-bom
trim_trailing_whitespace = true
insert_final_newline = true
[*.cs]
csharp_style_namespace_declarations = file_scoped:warning
csharp_prefer_braces = true:warning
dotnet_naming_rule.private_fields.style = camel_case_underscore
dotnet_naming_rule.private_fields.symbols = private_fields
dotnet_naming_rule.private_fields.severity = warning
// โโ Format the entire codebase โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
dotnet format // fixes style violations in all files
dotnet format --verify-no-changes // check only โ fails if violations found
// Run dotnet format --verify-no-changes in CI to enforce style gates
Common Mistakes
Mistake 1 โ Not using Directory.Build.props (property drift between projects)
โ Wrong โ each project has its own TargetFramework and Nullable settings; they drift and diverge over time.
โ Correct โ extract all shared properties into Directory.Build.props at the solution root; override in individual csproj only when needed.
Mistake 2 โ Skipping dotnet format in CI
โ Wrong โ code style inconsistency accumulates; developers argue about style in code reviews instead of logic.
โ
Correct โ run dotnet format --verify-no-changes as a required CI step; fail the build if style violations exist.