Claude Code Plugins

Community-maintained marketplace

Feedback

dotnet-guidelines

@roeibajayo/claude-tools
0
0

C# coding guidelines and best practices. MUST follow these rules.

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name dotnet-guidelines
description C# coding guidelines and best practices. MUST follow these rules. Use when reviewing/writing C# code or dotnet tasks.

IMPORTANT Server Guidelines

  • ALWAYS Use Primary Constructors for classes.
  • ALWAYS Prefer record types for immutable data structures.
  • NEVER mix multiple classes or DTOs in a single file, even if they are small. Filename ALWAYS matches the class or DTO name, for example UserDto.cs for a UserDto class.
  • Private fields should NOT be prefixed with _ (e.g., repository not _repository).
  • Add (.) to the end of all server-side log messages.
  • Use string? over string for nullable strings.
  • Use var for local variables when type is obvious.
  • Don't use Regions in code files.
  • Use Collection initializers for collections: instead of new List<string>(), use new() { "item1", "item2" }, and instead of list.ToArray() use [.. list].
  • Use Anonymous function static: instead of list.Select(x => new Dto(x.SameProperty)), use list.Select(static x => new Dto(x.SameProperty)).
  • ALWAYS use sealed accessor for classes or records if not intended for inheritance.
  • ALWAYS use internal accessor for internal classes or records.
  • NEVER inject or create HttpClient and IHttpClientFactory, instead use the IRestClient interface.
  • NEVER register services directly in IServiceCollection. Instead, use the ITransientService, IScopedService, or ISingletonService interfaces to register services with the appropriate lifetimes.
  • ALWAYS use ILogger with Structured logging to log, no string interpolation and no other logging methods.
  • ALWAYS use cancellation tokens for asynchronous methods.
  • ALWAYS use IMemoryCore for time-based in-memory caching, NEVER use IMemoryCache.
  • ALWAYS use Data Transfer Objects (DTO) for API communication, validated with attributes.
  • ALWAYS use x as a parameter name in lambdas and anonymous functions.
  • NEVER use try-catch blocks solely to log and rethrow exceptions.
  • If any backend changes are made, run dotnet build in the root and ensure no build errors for the entire solution.

Code Organization Principles

Avoid Unnecessary Wrapper Methods

Rule: Do NOT create wrapper methods for specific cases that simply call another method with fixed parameters. Call the base method directly instead.

Example - DON'T:

// ❌ Don't create this wrapper method for a single use case:
public async Task<int> CreateAgentHistoryClearedMessageAsync(int sessionId)
{
    var request = new CreateMessageRequest(
        Type: MessageType.System,
        Content: "Agent history has been cleared",
        Status: MessageStatus.Done
    );
    return await CreateMessageAsync(sessionId, request);
}

Example - DO:

// ✅ Instead, call CreateMessageAsync directly where needed:
await messageService.CreateMessageAsync(
    sessionId,
    new CreateMessageRequest(
        MessageType.System,
        "Agent history has been cleared",
        MessageStatus.Done
    )
);

When to create a helper method:

  • When there's complex logic beyond just parameter mapping
  • When the same combination is used in multiple places (3+ times)
  • When the method provides meaningful abstraction or validation