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.
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.
---
name: ".NET"
description: "Always-on rules for writing C# and ASP.NET Core services, project files and configuration."
applyTo: "**/*.cs,**/*.csproj,**/appsettings*.json"
---
# .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.
---
paths:
- "**/*.cs"
- "**/*.csproj"
- "**/appsettings*.json"
---
<!-- .NET — generated from instructions/backend/dotnet/dotnet.instructions.md for Claude Code. Edit that file, not this one. -->
# .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.