Verified August 2026

.NET and C# Cheatsheet: SDK, ASP.NET Core and EF Core

A field reference for modern .NET development: SDK workflow, target frameworks, C# 14 language features, ASP.NET Core, EF Core, MAUI, Aspire, packaging, diagnostics, deployment, and architecture decisions.

.NET 10LTS, supported until Nov 2028
C# 14Released Nov 2025
.NET 8/9Both retire Nov 2026
5.3.8Bootstrap CSS, no Bootstrap JS
0 of 0 complete
Quick reference

Daily Commands and Decisions

Use this when creating, debugging, testing, packaging, and shipping a normal .NET application.

NeedCommand or fileExampleGotcha
Create appdotnet newdotnet new webapi -n Billing.ApiTemplates change over SDK releases; pin SDK with global.json for teams.
Restore packagesdotnet restoredotnet restore Billing.slnx --locked-modeUse locked mode in CI once lock files are committed.
Builddotnet builddotnet build -c Release -warnaserrordotnet run builds implicitly unless --no-build is set.
Testdotnet testdotnet test --collect:"XPlat Code Coverage"Unit tests and integration tests need different fixture lifetimes.
Publishdotnet publishdotnet publish -c Release -r linux-x64 --self-contained falseRuntime-dependent is smaller; self-contained carries the runtime.
Inspect SDKsdotnet --list-sdksdotnet --infoInstalled SDK and target framework are different decisions.
Manage packagesdotnet packagedotnet add package Microsoft.EntityFrameworkCore.SqlServerCentral package management prevents version drift across projects.
Audit packagesdotnet list packagedotnet list package --outdated --include-transitiveTransitive upgrades can change runtime behavior even when direct references stay fixed.
EF migrationdotnet efdotnet ef migrations add AddInvoicesInstall matching EF tools and keep migrations reviewed as code.
Formatdotnet formatdotnet format --verify-no-changesRun in CI only after agreeing on analyzer severities.
Secretsdotnet user-secretsdotnet user-secrets set ConnectionStrings:Billing "...dev..."User secrets are local development storage, not production secret management.
Workloadsdotnet workloaddotnet workload install mauiWorkloads are SDK-scoped; CI images must install the same workloads developers use.
Practical starter workflow
dotnet new sln -n Commerce
dotnet new webapi -n Commerce.Api
dotnet new classlib -n Commerce.Domain
dotnet new xunit -n Commerce.Tests
dotnet sln Commerce.sln add Commerce.Api Commerce.Domain Commerce.Tests
dotnet add Commerce.Api reference Commerce.Domain
dotnet add Commerce.Tests reference Commerce.Domain
dotnet build -warnaserror
dotnet test
Version map

Current Releases to Target

Facts below were checked against Microsoft Learn on 2026-08-02. Treat release and support dates as volatile.

.NET 10 LTS release; supported until November 2028. Use for new long-lived services unless a dependency blocks it.
.NET 9 STS release; supported until November 2026. Keep only when upgrading immediately is not practical.
.NET 8 LTS release; also supported until November 2026. Common enterprise baseline, but no longer the newest LTS.
Platform

Runtime, SDK, Project Files, and Packages

The .NET platform is a build system, runtime, BCL, package ecosystem, and deployment model. Confusing these layers causes most environment bugs.

.NET SDK vs Runtime

SDK: developer toolchain with CLI, MSBuild, Roslyn compilers, templates, and workload support. Runtime: what executes compiled apps. Example: a build agent needs SDK 10.x; a production container may need only the ASP.NET Core runtime.

  • Use dotnet --list-sdks and dotnet --list-runtimes to diagnose mismatches.
  • Use global.json to pin SDK feature band for a repo.
  • The SDK includes CLI commands, MSBuild targets, Roslyn compilers, templates, analyzers, and optional workloads such as MAUI.
  • The runtime supplies CoreCLR execution, garbage collection, JIT compilation, type safety, exception handling, and host policy.
  • Gotcha: installing a runtime does not let you compile code.
BCL, CIL, Assemblies, and Metadata

The Base Class Library is the common API surface: System, collections, streams, JSON, HTTP, LINQ, threading, diagnostics, globalization, and cryptography. C# compiles to Common Intermediate Language plus metadata inside assemblies; the runtime loads assemblies and JIT-compiles methods as they execute.

  • Assemblies: .dll or .exe deployment and versioning units with a manifest, referenced assemblies, resources, and type metadata.
  • CIL/JIT: normal apps compile source to IL first, then the JIT emits native code for the current CPU at runtime.
  • ReadyToRun and NativeAOT: move more work to publish time; useful for startup-sensitive services or CLI tools, but dynamic code and reflection need testing.
  • Gotcha: assembly version, package version, file version, and target framework are separate concepts; confusing them makes binding and deployment bugs hard to diagnose.
Target Framework Monikers

TargetFramework says what API surface the project compiles against. Example: net10.0 for current cross-platform apps, net10.0-windows when using Windows-specific APIs.

  • TargetFrameworks multi-targets a library, for example net8.0;net10.0.
  • Prefer modern netX.0 targets for new libraries; use .NET Standard mainly for old compatibility requirements.
  • Gotcha: higher TFM can block consumers on older runtimes.
Project File Essentials
Minimal SDK-style project
<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>net10.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
  </PropertyGroup>
</Project>
  • Properties: Nullable, ImplicitUsings, LangVersion, RuntimeIdentifier, and publish properties change build output.
  • Items: PackageReference, ProjectReference, Compile, Content, and None control dependencies and included files.
  • Repo defaults: centralize shared settings in Directory.Build.props, package versions in Directory.Packages.props, and SDK selection in global.json.
  • Gotcha: TreatWarningsAsErrors is useful, but generated code or analyzer packages may need targeted suppressions instead of blanket disabling.
NuGet and Package Hygiene
  • Central package management: keep versions in Directory.Packages.props to prevent drift.
  • Lock files: use RestorePackagesWithLockFile and CI --locked-mode for deterministic restores.
  • Private feeds: keep credentials outside source via environment, credential providers, or CI secrets.
  • Package sources: keep nuget.config explicit for public and private feeds; use package source mapping when multiple feeds can serve the same ID.
  • Package creation: set package ID, version, license, repository URL, symbols, and README before publishing a reusable library.
  • Vulnerability review: audit direct and transitive packages during dependency updates, not only during incident response.
  • Gotcha: transitive package upgrades can change runtime behavior; review dependency diffs.
C# 14

Language Features and Daily Patterns

C# productivity comes from static types, async flow, pattern matching, LINQ, nullable analysis, and low-allocation APIs when needed.

Nullable Reference Types

Purpose: make nullability visible in the type system. Example: string? can be null; string should not be. Gotcha: it is static analysis, not a runtime guarantee.

Async/Await

Purpose: express non-blocking I/O while keeping straight-line control flow. Example: await http.GetFromJsonAsync<Invoice[]>("/invoices", ct). Gotcha: do not block with .Result or .Wait() in request paths.

  • Task represents an operation; Task<T> represents an operation with a result; ValueTask<T> is for measured allocation-sensitive APIs.
  • Async improves scalability for I/O-bound work; CPU-bound work still needs CPU time, often behind a queue or background worker.
  • Exceptions propagate through await; use normal try/catch around awaited calls.

LINQ

Purpose: query objects, XML, and providers with composable operators. Example: orders.Where(o => o.Total > 100).Select(o => o.Id). Gotcha: LINQ-to-Objects and EF SQL translation have different costs.

  • Method syntax: fluent operators such as Where, Select, GroupBy, OrderBy, Any, and FirstOrDefault.
  • Query syntax: SQL-like syntax that can be clearer for joins and grouping.
  • Deferred execution: many queries run only when enumerated; materialize with ToList() or ToArray() at a deliberate boundary.
  • Provider boundary: EF Core translates expression trees to SQL; unsupported methods either fail translation or force client-side work.

Pattern Matching

Purpose: branch on type, shape, values, and collection structure without fragile casts. Example: order is { Total: > 500, Status: OrderStatus.Pending }. Gotcha: clever nested patterns can become less readable than explicit guards.

  • Type pattern: message is PaymentReceived received checks and casts in one expression.
  • Property pattern: customer is { Address.Country: "US" } expresses object-shape checks.
  • Relational/logical patterns: score is >= 90 and <= 100 keeps range rules close to the branch.
  • List patterns: tokens is ["deploy", var service, ..] is useful for command parsers.

Records and Immutability

Purpose: concise value-oriented models with generated equality, deconstruction, formatting, and non-destructive mutation. Example: public sealed record Money(decimal Amount, string Currency);. Gotcha: record equality is value-based; do not use mutable navigation-heavy EF entities as records by default.

  • Use positional records for compact DTOs and events; use explicit properties when validation or serialization shape matters.
  • with expressions create modified copies, for example invoice with { Status = Paid }.
  • Record structs can avoid allocation for small values, but copying large structs can cost more than expected.

Span and Memory

Purpose: slice contiguous memory without allocations. Example: parse a protocol header from ReadOnlySpan<byte>. Gotcha: Span<T> is stack-only and cannot be stored on the heap.

C# 14 Additions

As of July 2026: C# 14 includes extension members, null-conditional assignment, unbound generic nameof, more span conversions, lambda parameter modifiers, field-backed properties, partial events/constructors, and user-defined compound assignments. Gotcha: language version still depends on SDK/tooling support.

C# 14 reference

C# Keywords Cheat Sheet

Every C# keyword grouped by job, with a one-line purpose each. C# has 77 reserved keywords (identifiers you can never reuse) plus a longer set of contextual keywords that only carry special meaning in a specific place and stay usable as ordinary identifiers elsewhere. Contextual keywords are marked ᶜ. Verified against the Microsoft Learn C# keywords reference (page dated 2026-06-05) for .NET 10 / C# 14.

Built-in Types

KeywordPurpose
boolBoolean value, true or false (alias for System.Boolean).
byte / sbyte8-bit unsigned (0–255) / signed (−128–127) integer.
short / ushort16-bit signed / unsigned integer.
int / uint32-bit signed / unsigned integer; int is the default integral literal type.
long / ulong64-bit signed / unsigned integer.
float / double32-bit / 64-bit IEEE-754 floating point; double is the default real literal.
decimal128-bit base-10 decimal; use for money to avoid binary rounding error.
charSingle 16-bit UTF-16 code unit.
stringImmutable sequence of characters (alias for System.String).
objectRoot of every type (alias for System.Object).
voidMethod returns no value.
nint / nuintᶜNative-sized signed / unsigned integer (32- or 64-bit per platform).
varᶜImplicitly-typed local; the compiler infers the static type from the initializer.
dynamicᶜBypasses static type checking; resolved at runtime. Avoid unless interop demands it.

Type & Member Declaration

KeywordPurpose
classReference type with identity; heap-allocated, reference semantics.
structValue type; copied by value, ideal for small immutable data.
recordᶜType with compiler-generated value equality and with copying; record struct for value semantics.
interfaceContract of members a type promises to implement.
enumNamed set of integral constants.
delegateType-safe reference to a method; basis of events and callbacks.
namespaceGroups types into a named scope.
usingAs a directive: imports a namespace or defines an alias.
eventMember exposing a delegate for publish/subscribe, restricting callers to +=/-=.
operatorDeclares an operator overload or conversion.
thisCurrent instance; also declares an indexer or (C# 14) an extension receiver.
baseAccesses the base class's members or constructor.
extensionᶜC# 14 extension block declaring extension members (properties, operators, statics), not just methods.

Access & Modifiers

KeywordPurpose
publicVisible everywhere.
privateVisible only inside the declaring type (default for class members).
protectedVisible to the type and its derived types.
internalVisible within the same assembly (default for top-level types).
staticMember belongs to the type, not an instance.
abstractIncomplete member/type that must be overridden/derived.
sealedPrevents further inheritance or overriding.
virtual / overrideMarks a member overridable / provides the derived implementation.
newAs a modifier: hides an inherited member. As an operator: allocates an instance.
constCompile-time constant, baked into callers.
readonlyField assignable only in declaration or constructor.
requiredᶜCaller must set this member during object initialization (C# 11+).
volatileField read/written without compiler/CPU reordering optimizations.
externMethod implemented externally, usually via P/Invoke.
unsafeEnables pointer types and pointer arithmetic in a scope.
fixedPins a variable so the GC cannot move it; declares fixed-size buffers.
partialᶜSplits a type or member across files; C# 14 adds partial constructors/events.
fileᶜType visible only within the source file (C# 11+); used by source generators.

Control Flow

KeywordPurpose
if / elseConditional branch.
switchMulti-way branch; also the switch expression form for pattern matching.
case / defaultA switch arm / the fallthrough arm (also the default-value expression).
forCounter-based loop.
foreach / inIterates any IEnumerable; in separates variable and source.
while / doTop-tested / bottom-tested loop.
break / continueExit the loop / skip to the next iteration.
gotoJumps to a label or switch case; rarely justified outside state machines.
returnExits a method, optionally with a value.
whenᶜGuard clause on a catch or a pattern-matching arm.

Exceptions, Checks & Locking

KeywordPurpose
try / catch / finallyGuard a block / handle an exception / run cleanup unconditionally.
throwRaises an exception; bare throw; in a catch preserves the stack trace.
checked / uncheckedEnable / suppress overflow checking for integral arithmetic.
lockAcquires a mutual-exclusion lock around a block (uses System.Threading.Lock in .NET 9+).
usingAs a statement/declaration: disposes an IDisposable at scope end.

Parameters, Refs & Memory

KeywordPurpose
refPass/return by reference; also ref struct and ref locals.
outPass by reference for output; the callee must assign it before returning.
inPass a readonly reference (avoids copying large structs).
paramsVariable-length argument list; C# 13 allows params spans and collections.
scopedᶜRestricts a ref's lifetime to the current scope (ref-safety, C# 11+).
stackallocAllocates a block on the stack, typically as a Span<T>.
sizeofSize in bytes of an unmanaged type.
notnullᶜGeneric constraint: the type argument must be a non-nullable type.
unmanagedᶜGeneric constraint: type argument is an unmanaged (blittable) type.
managed / unmanagedᶜCalling convention on a function pointer (delegate*).
allowsᶜC# 13 anti-constraint, e.g. allows ref struct, permitting ref-struct type arguments.

Type Tests, Conversions & Literals

KeywordPurpose
isType/pattern test; obj is Customer c tests and casts in one step.
asReference conversion returning null on failure (no exception).
typeofGets the System.Type for a type at compile time.
nameofᶜCompile-time string of a symbol's name; refactor-safe for logs and ArgumentNullException.
explicit / implicitDeclares a cast that requires / does not require a cast operator.
true / falseBoolean literals (and overloadable operators).
nullAbsence of a reference or of a nullable value.

Accessors, Properties & Async

KeywordPurpose
getᶜ / setᶜProperty/indexer read / write accessor.
initᶜAccessor settable only during object initialization (C# 9+).
valueᶜImplicit parameter holding the assigned value inside a set/init/add/remove.
fieldᶜC# 14: the compiler-generated backing field inside an accessor, so you skip declaring one.
addᶜ / removeᶜCustom event subscription / unsubscription accessors.
asyncᶜ / awaitᶜMarks an async method / suspends until a Task completes without blocking the thread.
yieldᶜyield return/yield break produce an iterator lazily.
withᶜNon-destructive copy of a record/struct with some members changed.

LINQ Query & Pattern Logic

KeywordPurpose
fromᶜStarts a query and introduces the range variable.
whereᶜQuery filter clause; also (reserved sense) a generic type constraint.
selectᶜProjects each element into the result shape.
groupᶜ / byᶜ / intoᶜGroups results by a key and continues the query.
orderbyᶜ / ascendingᶜ / descendingᶜSorts the sequence and sets direction.
joinᶜ / onᶜ / equalsᶜCorrelates two sequences on matching keys.
letᶜIntroduces a computed range variable mid-query.
andᶜ / orᶜ / notᶜLogical pattern combinators, e.g. is >= 1 and <= 9.
globalᶜ / aliasᶜglobal:: namespace qualifier; global using and extern aliases.
argsᶜThe implicit command-line arguments parameter in a top-level program.
App models

Choose the Right .NET Surface

Pick the runtime model around deployment, UI needs, latency, scaling, and team skill. Avoid using one framework for every problem.

ModelUse whenExampleWhen not to use
ASP.NET Core minimal APISmall HTTP APIs, microservices, internal toolsapp.MapGet("/health", () => Results.Ok())Complex MVC view workflows with lots of server-rendered UI conventions
ASP.NET Core MVC/Razor PagesServer-rendered business apps and admin workflowsRazor Page for invoice approvalPure JSON backend with no server-side views
BlazorC# web UI with component modelDashboard sharing validation models with backendTeams already standardized on React/Vue and needing broad JS ecosystem packages
.NET MAUICross-platform mobile/desktop from one C# codebaseLine-of-business tablet appPixel-perfect native consumer UI per platform
WPF / WinFormsWindows desktop, existing enterprise code, rich desktop controlsManufacturing workstation appMac/Linux first-party desktop target
.NET AspireLocal orchestration, service discovery, telemetry defaults for distributed appsAPI + worker + Redis + Postgres app hostSimple single-process app with no distributed dependencies
Worker serviceBackground jobs, queue consumers, schedulersHosted service processing payments queueRequest/response HTTP API only
NativeAOTFast startup, small deployment, restricted runtime feature set acceptableCLI tool or serverless functionHeavy reflection, runtime code generation, dynamic plugin loading
Data and web

ASP.NET Core, EF Core, APIs, and Security

Most production .NET work sits here: HTTP boundaries, persistence, validation, identity, telemetry, and operational resilience.

ASP.NET Core Request Pipeline

The pipeline is ordered middleware plus endpoints. Example order: exception handling, HTTPS redirection, static files, routing, authentication, authorization, endpoint mapping. Gotcha: authorization before authentication does not work as intended.

  • Core hosting pieces: Kestrel serves HTTP, the generic host wires configuration/logging/DI, and middleware composes request behavior.
  • Surface choices: minimal APIs for lean JSON endpoints, MVC/Razor Pages for server-rendered workflows, Blazor for component UI, and gRPC for high-throughput service calls.
  • Dependency injection: register services with singleton, scoped, or transient lifetimes; never inject scoped services into singletons without a scope factory.
  • Configuration: layer JSON, environment variables, command-line values, user secrets for local dev, and real secret stores for production.
  • Logging: use ILogger<T> with structured templates, log levels, scopes, and correlation IDs rather than string-concatenated messages.
Minimal API skeleton
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddProblemDetails();
builder.Services.AddOpenApi();
builder.Services.AddHealthChecks();
builder.Services.AddHttpClient("catalog", c => c.BaseAddress = new Uri("https://catalog.internal/"));

var app = builder.Build();
app.UseExceptionHandler();
app.MapOpenApi();
app.MapHealthChecks("/healthz");
app.MapGet("/orders/{id:int}", async (int id, OrdersDb db, CancellationToken ct) =>
    await db.Orders.FindAsync([id], ct) is { } order
        ? Results.Ok(order)
        : Results.NotFound());
app.Run();
EF Core
  • DbContext: unit-of-work boundary. Example: one scoped context per web request. Gotcha: do not keep a context as a singleton.
  • Migrations: source-controlled schema evolution. Example: dotnet ef migrations add AddInvoiceStatus.
  • Providers: SQL Server, SQLite, PostgreSQL, MySQL, Cosmos DB, and other providers differ in SQL translation and feature coverage.
  • Relationships: model keys, indexes, required/optional relationships, delete behavior, and concurrency tokens explicitly for important aggregates.
  • Tracking: default for updates; use AsNoTracking() for read-only queries.
  • Performance: project DTOs with Select, avoid N+1 queries, use pagination, prefer compiled queries only after measuring, and inspect generated SQL for hot paths.
  • Transactions: EF wraps SaveChanges in a transaction for supported providers; coordinate explicit transactions only when multiple operations must commit together.
  • When not to use: use Dapper or raw ADO.NET for heavily tuned SQL/reporting paths where hand-written SQL is clearer and faster.
Testing Web and Data Code
  • Unit tests: isolate domain logic with xUnit, NUnit, or MSTest; keep database, clock, network, and filesystem behind explicit seams.
  • Integration tests: use WebApplicationFactory for ASP.NET Core endpoints and test containers or dedicated databases for realistic persistence behavior.
  • EF tests: avoid assuming EF's in-memory provider behaves like a relational database; use SQLite or the real provider for SQL-sensitive behavior.
  • Coverage: coverage highlights untested code, but assertions and scenario quality matter more than a target percentage.
  • Gotcha: shared fixtures speed tests up but can leak state; reset databases and clocks deliberately.
API Design
  • Contracts: use request/response DTOs instead of exposing EF entities.
  • Errors: return RFC 7807-style problem details for predictable client handling.
  • Versioning: introduce explicit versioning when multiple active clients need independent evolution.
  • HTTP semantics: use status codes, idempotency, caching headers, pagination, filtering, and optimistic concurrency intentionally.
  • Validation: validate boundary models before command execution; keep domain invariants inside the domain model or application service.
  • OpenAPI: generate and verify docs from the actual app endpoints. Gotcha: docs that drift are worse than no docs.
Security Defaults
  • Use HTTPS, secure cookies, strict auth policies, and least-privilege service identities.
  • Validate inputs at the boundary and encode outputs in UI contexts.
  • Store secrets in environment, managed identity, user secrets for local dev, or a real secret store.
  • Use ASP.NET Core authentication schemes and authorization policies rather than hand-rolled role checks scattered through controllers.
  • Use Data Protection APIs for framework-managed tokens and cookies; use established cryptography APIs and libraries for application data, not custom crypto.
  • Configure CORS narrowly by origin, method, and header; do not use permissive wildcard policies with credentials.
  • Gotcha: logging tokens, connection strings, or PII creates a production incident.
Operations

Diagnostics, Performance, and Deployment

Modern .NET gives good tools, but you still need explicit telemetry, measured optimization, and repeatable deployment.

Observability

Use structured logs, metrics, traces, health checks, and correlation IDs. Example: OpenTelemetry exporting traces to your collector. Gotcha: logs without request IDs are painful during incidents.

  • Logging: capture decisions and failures with message templates and relevant IDs, not secrets or raw payloads.
  • Metrics: count requests, errors, queue depth, dependency latency, allocation rate, and domain events that indicate business health.
  • Tracing: propagate context across HTTP, gRPC, queues, and database calls so one request can be followed across services.

GC and Allocation

Measure before optimizing. Example: use dotnet-counters for allocation rate and GC pressure, then profile hot paths. Gotcha: premature Span<T> rewrites can obscure code without improving throughput.

  • Workstation GC: optimized for client responsiveness; common for desktop apps and tools.
  • Server GC: optimized for throughput on multi-core servers; common for ASP.NET Core services.
  • Common pressure sources: large object heap churn, unnecessary string allocations, sync-over-async, and buffering full payloads.

Containers

Use official runtime images, non-root users where possible, and small publish output. Example: build in SDK image, run in ASP.NET runtime image. Gotcha: self-contained containers are larger and patch differently.

  • Multi-stage builds: restore/build/publish in an SDK image, copy only publish output into an ASP.NET or runtime image.
  • Runtime-dependent: smaller image that receives runtime fixes from base image updates.
  • Self-contained: includes runtime bits; useful when host runtime is unavailable, but patching requires republishing the app.

Publish and Deployment Modes

Purpose: choose output based on host control, startup, size, and runtime patching. Example: dotnet publish -c Release -r linux-x64 -p:PublishTrimmed=true. Gotcha: trimming and AOT can break reflection-heavy libraries unless tested from published output.

  • Framework-dependent: smallest app output, requires compatible runtime installed on the host or in the base image.
  • Self-contained: deploys app plus runtime for a specific RID such as linux-x64 or win-x64.
  • Single-file: packages app into one executable; extraction and native dependency behavior still need validation.
  • NativeAOT: fastest startup and reduced runtime footprint for compatible apps; validate source generators, serializers, reflection, and dynamic proxy libraries early.

Resilience

Timeouts, retries, circuit breakers, bulkheads, and idempotency protect distributed systems. Example: retry transient SQL or HTTP 503 with jitter. Gotcha: retrying non-idempotent writes can duplicate side effects.

Debug Tools

Useful CLI tools include dotnet-trace, dotnet-counters, dotnet-dump, and test loggers. Gotcha: collect diagnostics from a matching environment before guessing.

  • dotnet-counters monitor --process-id 1234 System.Runtime watches GC, exceptions, thread pool, and allocation pressure.
  • dotnet-trace collect --process-id 1234 captures runtime events for later analysis.
  • dotnet-dump collect --process-id 1234 captures memory state for leaks, hangs, and crash investigation.
  • dotnet test --logger trx --blame-hang helps diagnose test failures that only appear in CI.

Build, Test, and CI/CD

Purpose: make restore, build, test, package, and deploy repeatable outside a developer IDE. Example: CI runs dotnet restore --locked-mode, dotnet build --no-restore -warnaserror, then dotnet test --no-build. Gotcha: an IDE-only workflow hides missing SDKs, workloads, and environment settings.

  • Commit solution files, project files, lock files, analyzer config, and central package files so CI sees the same graph.
  • Cache NuGet packages carefully; stale caches can hide restore and vulnerability problems.
  • Produce artifacts from a clean release publish, not from bin/Debug output.

Architecture Boundaries

Keep domain logic independent from transport, persistence, and UI. Example: controllers call application services; EF implementations live behind repository/query abstractions where useful. Gotcha: over-abstracting CRUD can add noise.

  • Scalability: use caching, queues, load balancing, and microservices only when the operational cost is justified.
  • Maintainability: keep validation, transactions, authorization, and external calls in predictable layers.
  • Cost: monitor resource usage and match service tiers to measured load instead of defaulting to oversized hosts.
Common mistakes

.NET Anti-Patterns

These cause real production bugs in otherwise ordinary .NET systems.

Blocking async code.

Calling .Result or .Wait() on async operations can starve thread pools or deadlock older synchronization contexts. Await all the way through.

Leaking DbContext lifetime.

A singleton context or context captured by background work causes stale tracking, threading issues, and connection pressure. Use scoped lifetimes and factories where needed.

Exposing EF entities as API contracts.

Persistence models leak internal shape, navigation cycles, and future schema changes. Use DTOs for external contracts.

Ignoring cancellation.

HTTP disconnects, job shutdown, and timeouts should flow through tokens. Pass CancellationToken into EF, HTTP, and long-running work.

Runtime version drift.

Developers, CI, containers, and production can silently use different SDK/runtime versions. Pin SDKs and log runtime info at startup.

Reflection-heavy NativeAOT surprises.

AOT trims unused code and restricts dynamic patterns. Test publish output early when targeting AOT or trimming.

Creating HttpClient per call.

Repeated clients can exhaust sockets and lose handler pooling. Use IHttpClientFactory, typed clients, or a deliberately managed long-lived client.

Using EF in-memory tests as proof of SQL behavior.

The in-memory provider does not enforce relational constraints or SQL translation. Use SQLite or the real provider for query and migration behavior.

Leaking secrets through config and logs.

User secrets are for local development only, and production secrets belong in managed stores. Scrub tokens, passwords, and PII from logs.

Publishing without testing the published output.

Debug builds can pass while trimmed, single-file, self-contained, or NativeAOT output fails. Smoke-test the exact artifact you deploy.

Primary references

Verification Sources

Use official Microsoft docs first for volatile platform facts and API behavior.

No matching sections. Clear filters or search a broader term.