Skip to content
Development
Skill

/csharp-rules

C#/.NET coding rules: style, patterns, security, testing. Triggers: .cs, .csproj, .sln, ASP.NET, ASP.NET Core, EF Core, LINQ, NUnit, xUnit, dotnet.

From plugin
ai-toolkit
161111 skills44 agents
Install
$ npx -y skills add softspark/ai-toolkit --skill csharp-rules --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/csharp-rules

Context preview

The summary Claude sees to decide when to auto-load this skill.

C#/.NET coding rules: style, patterns, security, testing. Triggers: .cs, .csproj, .sln, ASP.NET, ASP.NET Core, EF Core, LINQ, NUnit, xUnit, dotnet.

SKILL.md

csharp-rules.SKILL.md
name: csharp-rules
description: "C#/.NET coding rules: style, patterns, security, testing. Triggers: .cs, .csproj, .sln, ASP.NET, ASP.NET Core, EF Core, LINQ, NUnit, xUnit, dotnet."
effort: medium
user-invocable: false
allowed-tools: Read

C#/.NET Rules

These rules come from `app/rules/csharp/` in ai-toolkit. They cover the project's standards for coding style, frameworks, patterns, security, and testing in C#/.NET. Apply them when writing or reviewing C#/.NET code.

C# Coding Style

Naming

  • PascalCase: classes, structs, enums, interfaces, methods, properties, events.
  • camelCase: local variables, parameters, private fields.
  • Prefix interfaces with `I`: `IUserRepository`, `IDisposable`.
  • Prefix private fields with `_`: `private readonly ILogger _logger;`.
  • UPPER_SNAKE: not conventional in C#. Use PascalCase for constants.

Nullable Reference Types

  • Enable `<Nullable>enable</Nullable>` in all projects.
  • Use `string?` only when null is semantically meaningful.
  • Use `!` (null-forgiving) operator sparingly -- only when compiler cannot infer.
  • Use `??` (null-coalescing) and `?.` (null-conditional) for safe navigation.
  • Use `required` modifier (C# 11) on properties that must be set at initialization.

Records and Types

  • Use `record` for immutable value objects and DTOs.
  • Use `record struct` for small, stack-allocated value types.
  • Use `init` properties for immutable-after-construction objects.
  • Use `with` expressions for non-destructive mutation of records.
  • Use primary constructors (C# 12) for concise class definitions.

Pattern Matching

  • Use `is` pattern for type checks: `if (obj is string s)`.
  • Use `switch` expressions for exhaustive matching over enums/types.
  • Use property patterns: `user is { Age: > 18, Role: "admin" }`.
  • Use relational patterns: `size is > 0 and < 100`.
  • Use list patterns (C# 11): `numbers is [1, 2, .., var last]`.

Async/Await

  • Suffix async methods with `Async`: `GetUserAsync()`.
  • Return `Task<T>` or `ValueTask<T>`, never `void` (except event handlers).
  • Use `await` with `ConfigureAwait(false)` in library code.
  • Use `CancellationToken` parameters in all async public APIs.
  • Prefer `ValueTask<T>` when synchronous completion is common.

File Organization

  • One type per file. File name matches type name.
  • Use file-scoped namespaces (C# 10): `namespace MyApp.Services;`.
  • Order members: fields, constructors, properties, public methods, private methods.
  • Use `global using` directives in a single `GlobalUsings.cs` file.

Formatting

  • Use `.editorconfig` with C# style rules committed to the repository.
  • Use `dotnet format` for automated formatting.
  • Use Roslyn analyzers for compile-time style enforcement.
  • Max line length: 120 characters.

C# Frameworks

ASP.NET Core

  • Use minimal APIs for simple endpoints. Use controllers for complex APIs.
  • Use `[ApiController]` attribute for automatic model validation and error responses.
  • Use `Results.Ok()`, `Results.NotFound()` for typed HTTP results.
  • Use endpoint filters / middleware for cross-cutting concerns.
  • Use `IHostedService` / `BackgroundService` for long-running background tasks.
  • Map routes with `app.MapGet()`, `app.MapPost()` for minimal API style.

Entity Framework Core

  • Use code-first migrations: `dotnet ef migrations add`, `dotnet ef database update`.
  • Use `DbContext` with scoped lifetime (one per request).
  • Use `AsNoTracking()` for read-only queries. Use `AsTracking()` only for updates.
  • Use `Include()` / `ThenInclude()` for eager loading related entities.
  • Use shadow properties for audit fields (`CreatedAt`, `UpdatedAt`).
  • Use `HasQueryFilter()` for soft-delete and multi-tenancy global filters.

Blazor

  • Use Blazor Server for internal tools. Use Blazor WASM for public-facing SPAs.
  • Use `@inject` for dependency injection in components.
  • Use `EventCallback<T>` for parent-child component communication.
  • Use `CascadingValue` for deeply shared state (theme, auth).
  • Use `StateContainer` pattern with events for cross-component state management.

SignalR

  • Use strongly-typed hubs: `Hub<IClientMethods>` for compile-time safety.
  • Use `HubContext<T>` for sending messages from outside hubs.
  • Use groups for targeted broadcasting: `Groups.AddToGroupAsync()`.
  • Configure automatic reconnection on the client side.

MassTransit / Messaging

  • Use MassTransit for message bus abstraction over RabbitMQ/Azure Service Bus.
  • Define messages as `record` types for immutability.
  • Use consumers (`IConsumer<T>`) for message handling.
  • Use sagas for long-running, multi-step workflows with state.
  • Use retry and circuit breaker policies for transient failures.

Logging

  • Use `ILogger<T>` via DI. Never instantiate loggers manually.
  • Use structured logging: `_logger.LogInformation("User {UserId} logged in", userId)`.
  • Use Serilog with sinks for structured, centralized logging.
  • Use log scopes for request correlation: `using (_logger.BeginScope(...))`.

Configuration

  • Use `appsettings.json` + environment-specific overrides + environment variables.
  • Bind configuration sections to strongly-typed classes with `IOptions<T>`.
  • Use `IOptionsMonitor<T>` for configuration that changes at runtime.
  • Validate configuration at startup with `ValidateDataAnnotations()`.

Health Checks

  • Use `app.MapHealthChecks("/health")` for liveness probes.
  • Register custom health checks for database, cache, and external service dependencies.
  • Use `AspNetCore.HealthChecks.*` NuGet packages for common checks.

C# Patterns

Error Handling

  • Use exceptions for truly exceptional conditions. Use `Result<T>` pattern for expected failures.
  • Create domain exception hierarchies: `class DomainException : Exception`.
  • Use `when` clause in catch: `catch (HttpRequestException e) when (e.StatusCode == 404)`.
  • Use `ExceptionDispatchInfo.Capture(e).Throw()` to preserve original stack trace.
  • Return `Result<T, Error>` types for operations with expected failure modes.

Asyn

Read more
Ships withai-toolkit

Professional-grade AI coding toolkit with multi-platform support. Machine-enforced safety, 109 skills, 44 agents, expanded lifecycle hooks, persona presets, experimental opt-in plugin packs, and benchmark tooling — works with Claude Code, Claude Chat/Cowork,

Get the whole plugin