---
description: C# Tooling and Ecosystem
alwaysApply: false
---

# C# Tooling and Ecosystem

The .NET toolchain, project configuration, and CI/CD patterns.

## Essential CLI

```bash
dotnet build --warnaserror          # Build with warnings as errors
dotnet test --collect:"XPlat Code Coverage"  # Test with coverage
dotnet format --verify-no-changes   # CI code style check
dotnet watch --project src/MyApp.Api  # Hot reload dev
```

## Directory.Build.props

```xml
<Project>
  <PropertyGroup>
    <TargetFramework>net9.0</TargetFramework>
    <Nullable>enable</Nullable>
    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
    <EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
    <AnalysisLevel>latest-recommended</AnalysisLevel>
    <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
  </PropertyGroup>
</Project>
```

## Central Package Management

Use `Directory.Packages.props` — single source of truth for all NuGet versions across the solution.

## .editorconfig Essentials

```ini
[*.cs]
csharp_style_var_when_type_is_apparent = true:suggestion
csharp_prefer_simple_using_statement = true:warning
csharp_style_namespace_declarations = file_scoped:warning
dotnet_naming_rule.private_fields_should_be_camel_case.severity = error
```

## Analyzers

```xml
<ItemGroup>
  <PackageReference Include="SonarAnalyzer.CSharp" PrivateAssets="all" />
  <PackageReference Include="Roslynator.Analyzers" PrivateAssets="all" />
</ItemGroup>
```

## Logging (Serilog)

```csharp
// Structured logging — always use templates, never interpolation
logger.LogInformation("Processing order {OrderId} for {CustomerId}", order.Id, customerId);
// NOT: logger.LogInformation($"Processing {order.Id}"); // Defeats structured logging
```

## CI Essentials

```bash
dotnet restore
dotnet build --warnaserror
dotnet format --verify-no-changes
dotnet test --collect:"XPlat Code Coverage"
```

## Anti-Patterns

- **Hardcoded connection strings** — use configuration and user-secrets
- **Version conflicts** — use `Directory.Packages.props` for central management
- **Skipping `dotnet format` in CI** — style drift makes reviews noisier
