Org Skills

.NET

Always-on rules for writing C# and ASP.NET Core services, project files and configuration.

Raw Source
What it isAlways-on coding rules. GitHub Copilot applies them to files matching **/*.cs,**/*.csproj,**/appsettings*.json; the Claude Code version is a path-scoped rule generated from the same file. Why use instructions →

Install

This repository (recommended)

Adds .github/instructions/dotnet.instructions.md — commit it so everyone's Copilot follows the same rules.

npx -y github:AGCO-Global/org-skills add instructions dotnet

Just for me, every repository

Save it in your user profile instead.

npx -y github:AGCO-Global/org-skills add instructions dotnet --user

Use it

Nothing to invoke — edit a matching file and Copilot picks the rules up. Adjust applyTo if your repository layout differs.

This repository (recommended)

Adds .claude/rules/dotnet.md — commit it. Claude loads it when it reads a matching file.

npx -y github:AGCO-Global/org-skills add instructions dotnet --tool claude

Just for me, every repository

Save it in your user profile instead.

npx -y github:AGCO-Global/org-skills add instructions dotnet --tool claude --user

Use it

Nothing to invoke. Adjust the paths globs if your repository layout differs.

Commands run in your repository folder and need Node.js 20+. They use your normal git sign-in to GitHub, so they work while the repository is private. Run npx -y github:AGCO-Global/org-skills list to see everything available.

Settings

name: ".NET"
description: "Always-on rules for writing C# and ASP.NET Core services, project files and configuration."
applyTo: "**/*.cs,**/*.csproj,**/appsettings*.json"

Instructions Copilot follows

.NET rules

Target the current LTS unless global.json or <TargetFramework> pins otherwise; check before using newer APIs.

Endpoints and structure

  • Keep endpoints thin: bind, validate, call one service or handler, map the result. No EF queries or business rules in Program.cs or controllers.
  • For new APIs, prefer minimal APIs with MapGroup per feature and TypedResults; stay with controllers where the codebase already uses them.
  • Return errors as ProblemDetails (AddProblemDetails(), Results.Problem); never return exception messages or stack traces to clients.
  • Validate every request DTO at the boundary (FluentValidation or data annotations) and reject unknown or over-long input.
  • Put RequireAuthorization() or [Authorize] with a named policy on every endpoint; add AllowAnonymous explicitly and rarely. Check resource ownership, not just authentication, to prevent IDOR.

Dependency injection and configuration

  • Match lifetimes: DbContext is scoped; never inject scoped services into singletons. Use IServiceScopeFactory in background services.
  • Use constructor injection; never call IServiceProvider.GetService in business code.
  • Bind configuration to typed options with .ValidateDataAnnotations().ValidateOnStart(). Bad config fails at startup, not in production traffic.
  • Never put secrets in appsettings*.json or source. Use User Secrets locally and Azure Key Vault or pipeline secret variables in deployed environments; prefer managed identity over passwords.
  • Use appsettings.{Environment}.json only for non-secret differences.

Async and resilience

  • Go async all the way; never .Result, .Wait() or .GetAwaiter().GetResult() on request paths. It causes thread-pool starvation.
  • Accept a CancellationToken and pass it to every I/O call (EF Core, HttpClient, streams).
  • No async void except event handlers; no fire-and-forget tasks from requests. Use a queue or BackgroundService.
  • Create HTTP clients through IHttpClientFactory (typed clients) with timeouts and the standard resilience handler; never new HttpClient() per call.

Data access

  • Use AsNoTracking() and project to DTOs with Select for reads; do not return entities from APIs.
  • Avoid N+1 queries: load related data with Include or projection, not queries in a loop.
  • Never build SQL by string concatenation; use LINQ, parameters or FromSql with interpolation (parameterized).
  • Apply schema changes through reviewed EF migrations using expand/contract; never EnsureCreated or auto-migrate in production.
  • Use decimal for money and UTC DateTimeOffset for time.

Code quality

  • Enable <Nullable>enable</Nullable> and treat nullable warnings as errors; do not silence them with !.
  • Use structured logging with message templates (logger.LogInformation("Order {OrderId} created", id)), not string interpolation; never log tokens, passwords or PII.
  • Catch specific exceptions only; no empty catch blocks.
  • Keep package versions central (Directory.Packages.props) and do not add packages without a clear need; watch dotnet list package --vulnerable.
  • Cover new behaviour with xUnit tests; use WebApplicationFactory for endpoint tests and Testcontainers over the EF in-memory provider.

Go deeper: for larger tasks use the dotnet-development, dotnet-architecture, dotnet-testing, dotnet-performance and api-design skills, and backend-code-review before opening a pull request.