Claude-skill-registry dotnet-guidelines

IMPORTANT Server Guidelines

install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/dotnet-guidelines" ~/.claude/skills/majiayu000-claude-skill-registry-dotnet-guidelines && rm -rf "$T"
manifest: skills/data/dotnet-guidelines/SKILL.md
source content

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.
  • 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