Agent Skills: C# Backend Engineering

Apply practical C# and .NET backend engineering standards for service implementation, refactoring, and backend-focused code reviews. Use when building or reviewing backend services for language best practices, project and layer boundaries, data-access patterns, resilience controls, observability, security baselines, and common backend anti-pattern detection. For deep NUnit fixture design use $qa-testing-nunit, for NUKE pipeline target work use $ops-nuke-cicd, and for deterministic logging rewrites use $dev-structured-logs.

UncategorizedID: vasilyu1983/ai-agents-public/software-csharp-backend

Install this agent skill to your local

pnpm dlx add-skill https://github.com/vasilyu1983/AI-Agents-public/tree/HEAD/frameworks/shared-skills/skills/software-csharp-backend

Skill Files

Browse the full folder contents for software-csharp-backend.

Download Skill

Loading file tree…

frameworks/shared-skills/skills/software-csharp-backend/SKILL.md

Skill Metadata

Name
software-csharp-backend
Description
"Applies C# and .NET backend standards. Use when shaping API boundaries, data access, resilience, observability, or security defaults."

C# Backend Engineering

Quick Reference

| Decision | Default | Notes | |----------|---------|-------| | Runtime | .NET 10 + C# 14 (LTS, GA Nov 2025, supported through ~Nov 2028) | .NET 8 LTS ends Nov 10, 2026 — verify current dates at dotnet support policy; treat continued .NET 8 targeting as a tracked migration, not a comfortable steady state | | API style | Minimal API for new endpoints | Controllers for large CQRS surface with many filters/action results | | Persistence (SQL, write-heavy) | EF Core | Use Dapper when query shapes are complex and hand-tuned SQL wins | | Persistence (SQL, query-heavy) | Dapper | Pair with EF Core for write path if aggregates exist | | Persistence (document) | MongoDB driver | Use when schema variability is genuine, not habitual | | Background worker | IHostedService / BackgroundService | Add lease, graceful shutdown, and poison-message handling from day one | | Resilience | Microsoft.Extensions.Resilience (Polly v8) | Standard pipeline: retry → circuit breaker → timeout | | OpenAPI | Built-in ASP.NET Core OpenAPI (Microsoft.AspNetCore.OpenApi) | Do not add Swashbuckle unless repo already uses it |

Route other tasks:

  • NUnit fixture design, WireMock/Testcontainers setup, or flake reduction → $qa-testing-nunit
  • nuke/Build.cs, CI target sequencing, or artifact publication → $ops-nuke-cicd
  • Legacy ILogger or Serilog rewrite automation → $dev-structured-logs

When to Use This Skill

  • Building or reviewing C# / .NET backend services
  • Choosing between ASP.NET Core API styles (controller, minimal API, background worker)
  • Implementing data access with EF Core, Dapper, or MongoDB
  • Adding resilience, observability, or security baselines to .NET services
  • Refactoring .NET backend code or detecting common anti-patterns

When NOT to Use This Skill

Workflow

  1. Classify the requested change (new feature, refactor, bug fix, review).
  2. Choose runtime shape before implementation details. Load references/scenario-guides.md and, for HTTP services, references/aspnet-core-api-patterns.md.
  3. Apply language and coding standards. Load references/csharp-language-practices.md and references/dotnet-coding-standards.md.
  4. Confirm architecture and boundaries before editing internals. Load references/backend-architecture-principles.md and references/modular-architecture-principles.md.
  5. Choose persistence and consistency strategy from query/write shape. Load references/data-access-patterns.md; if EF Core is selected, load references/efcore-persistence-patterns.md.
  6. Add resilience behavior for outbound I/O and long-running work. Load references/reliability-and-resilience.md and references/resilience-policy-defaults.md.
  7. Define tests by risk and boundary. Load references/testing-practices.md.
  8. Add logs, traces, metrics, health probes, and operability defaults. Load references/observability-standards.md, and for API/runtime deployment defaults load references/runtime-ops-checklist.md. If the service is distributed or cloud-native by design, also load references/scenario-guides.md for the Aspire-oriented profile.
  9. Validate auth, validation, and secrets handling. Load references/security-baseline.md.
  10. Run feedback loop validation for changed behavior. For NUKE-based repositories, run BuildAll, LocalUnitTest, ApiTest (when relevant), and TestAll; use $ops-nuke-cicd for pipeline-target edits.
  11. Run final review against anti-pattern checklist. Load references/code-review-checklist.md.

ASCII Flow

C# backend task
  -> Identify API, worker, data access, or service boundary
  -> Confirm .NET version, hosting model, DI, and persistence choices
  -> Design validation, auth, errors, retries, and observability
  -> Implement bounded slice with unit and integration tests
  -> Check EF, async, cancellation, and deployment traps
  -> Run focused verification and capture follow-up risks

Decision Tree

  • If the issue is naming, nullability, exception usage, or async flow, read references/csharp-language-practices.md.
  • If the issue is project layout, DI, configuration, or layering, read references/dotnet-coding-standards.md.
  • If the issue is service boundaries or clean architecture drift, read references/backend-architecture-principles.md.
  • If the issue is module boundaries, composition hosts, or modular-monolith tradeoffs, read references/modular-architecture-principles.md.
  • If the issue is API style, middleware ordering, ProblemDetails, OpenAPI, request timeouts, rate limiting, health/readiness, or graceful shutdown, read references/aspnet-core-api-patterns.md.
  • If the issue is SQL/Mongo/EF access, pagination, transactions, idempotency, or N+1, read references/data-access-patterns.md.
  • If EF Core is selected for relational persistence, also read references/efcore-persistence-patterns.md.
  • If the issue is system profile specific (high-throughput API, event-driven worker, multi-tenant service, distributed/Aspire host), read references/scenario-guides.md.
  • If the issue is retry/timeout/circuit behavior, cancellation propagation, standard resilience handler behavior, or worker reliability, read references/reliability-and-resilience.md and references/resilience-policy-defaults.md.
  • If the issue is container/runtime readiness, startup config validation, HybridCache defaults, or deployment reliability gates, read references/runtime-ops-checklist.md.
  • If the issue is target framework constraints, package/API compatibility, multi-targeting, or migration between .NET Framework/netstandard2.0 and modern .NET, read references/version-compatibility-notes.md.
  • If the issue is flaky tests, fake time control, or weak coverage strategy, read references/testing-practices.md.
  • If the issue is logs/traces/metrics/health checks, read references/observability-standards.md.
  • If the issue is input validation, auth boundaries, secret handling, or secure defaults, read references/security-baseline.md.
  • If the task is reviewing a PR for backend quality risks, read references/code-review-checklist.md.
  • If the task is designing or fixing build-test pipeline loop behavior, use $ops-nuke-cicd.
  • If the task needs deep HTTP controller + CQRS error-contract design, keep it in this skill and align handler/result patterns to the repository's existing conventions rather than introducing new framework requirements by default.

Do / Avoid

| Do | Avoid | |----|-------| | Keep application services small and explicit about dependencies | Coupling domain logic directly to HTTP, DB driver types, or framework-specific classes | | Return deterministic domain/application results for expected failures | Swallowing exceptions or replacing root causes with vague error messages | | Pass CancellationToken through every async layer and external call | Letting cancellation stop at the controller while downstream calls continue | | Model options with IOptions<T> validation; fail fast on invalid startup config | Binding configuration directly into services without options validation | | Choose API style intentionally; keep middleware ordering explicit | Mixing minimal APIs, controllers, and bespoke endpoint frameworks without a clear error-shape policy | | Use built-in ASP.NET Core OpenAPI and ProblemDetails before adding third-party wrappers | Adding Swashbuckle or MediatR when built-in plumbing is sufficient | | Keep persistence choices aligned to use-case shape, not team habit | Using retries without timeout and idempotency guarantees | | Make telemetry and security checks part of definition of done | Shipping endpoints without structured logs, traces, metrics, and health signals | | Write tests at unit and integration seams separately | Mixing unit and integration concerns in the same test fixture | | — | Using async void outside event handlers | | — | Sharing one DbContext instance across concurrent operations/threads | | — | Captive dependencies (singleton depending on scoped service) |

Known Traps

  • Mixing minimal APIs, controllers, and bespoke endpoint frameworks without a clear contract strategy or error-shape policy.
  • Letting cancellation stop at the controller boundary while downstream HTTP, EF Core, queue, or cache calls continue running.
  • Treating EF Core defaults as safe under load: lazy loading, implicit tracking, and missing query shaping frequently create hidden cost.
  • Using retries around non-idempotent handlers, transaction scopes, or third-party calls without dedupe or timeout coordination.
  • Shipping background workers without graceful shutdown, lease or lock ownership, or poison-message handling.
  • Binding configuration directly into services without options validation, startup failure checks, or explicit secret handling.
  • Choosing Native AOT for a service that depends on EF Core, reflection-based JSON, or dynamic plugin loading — EF Core is not fully AOT-compatible today, and unbounded reflection breaks at publish/trim time. Verify each dependency's AOT/trim compatibility before committing, or keep the service on the standard runtime.
  • Instantiating new HttpClient() per call or per request instead of resolving it through IHttpClientFactory/AddHttpClient<T> — this exhausts sockets under load (new HttpClient() disposed per call) or goes DNS-stale (one long-lived static instance) if done by hand.
  • Leaving Server GC (the ASP.NET Core default) unexamined in a memory-constrained or high-density container deployment — Server GC sizes heaps to the visible processor count, which can over-allocate memory on small/shared containers. Use DOTNET_GCHeapHardLimit/DATAS (Dynamic Adaptation to Application Sizes — opt-in on .NET 8, default-on from .NET 9) or switch to Workstation GC for high-density, low-CPU hosting; keep Server GC for dedicated, CPU-bound API pods.

Common Anti-Patterns

  • Building clean architecture layers that are mostly pass-through wrappers with no boundary or policy value.
  • Returning exceptions for expected domain outcomes instead of explicit result or error contracts.
  • Sharing repository abstractions everywhere even when the real need is a focused query handler or aggregate persistence boundary.
  • Hiding cross-cutting behavior inside ad hoc helpers instead of using middleware, filters, options, or resilience handlers deliberately.
  • Using integration tests as the only safety net while unit seams, fake time, and deterministic failure cases stay untested.

Navigation

References

Templates

Related Skills

Freshness Protocol

When users ask version-sensitive questions about .NET, C#, or ASP.NET Core, verify current information before answering.

Trigger Conditions

  • "What's the latest .NET LTS version?"
  • "Should I use EF Core or Dapper?"
  • "What's new in ASP.NET Core / C#?"
  • "Is [pattern/library] still recommended for .NET?"

How to Freshness-Check

  1. Start from data/sources.json (official docs, release notes, support policies).
  2. Run a targeted web search for the specific .NET component.
  3. Prefer official Microsoft docs over blogs for versions and support windows.

What to Report

  • Current landscape: what is stable and widely used now
  • Emerging trends: what is gaining traction (and why)
  • Deprecated/declining: what is falling out of favor (and why)
  • Recommendation: default choice + 1-2 alternatives, with trade-offs

Fact-Checking

  • Known bugs, regressions, framework/compiler/runtime footguns, and version-specific crash or workaround guidance must be verified against current primary web sources before being treated as current fact.
  • Use web search/web fetch to verify current external facts, versions, pricing, deadlines, regulations, or platform behavior before final answers.
  • Prefer primary sources; report source links and dates for volatile information.
  • If web access is unavailable, state the limitation and mark guidance as unverified.

Learnings Loop

Before applying this skill on a non-trivial task, read learnings.consolidated.md in this directory (and learnings.md if present).

After applying it, if you encountered a pattern worth remembering, a mistake worth preventing, or a domain fact that surprised you, append one dated bullet to learnings.md via agents-skills-feedback-loop/scripts/append_learning.py. Do not modify SKILL.md itself.