dotnet-development

.NET Development Skill

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "dotnet-development" with this command: npx skills add ibutters/claudecodeplugins/ibutters-claudecodeplugins-dotnet-development

.NET Development Skill

Execute this process for any .NET implementation task:

  1. Analysis Phase (Required)

Before writing code, perform these steps:

1.1. Identify domain concepts: List all aggregates, entities, and value objects involved in this change 1.2. Determine affected layer: Specify whether changes target Domain, Application, or Infrastructure 1.3. Map SOLID principles: Document which principles apply and how they guide the design 1.4. Assess security requirements: Identify authorization rules and data protection needs

  1. Architecture Review (Required)

Verify the approach against these criteria:

2.1. Check aggregate boundaries: Confirm they preserve transactional consistency 2.2. Apply Single Responsibility: Ensure each class has exactly one reason to change 2.3. Enforce Dependency Inversion: Verify dependencies point inward (Infrastructure → Application → Domain) 2.4. Validate domain encapsulation: Confirm business logic resides in domain objects, not services

  1. Implementation

Execute with these standards:

3.1. Use modern C# features: Apply C# 14 syntax (primary constructors, collection expressions, pattern matching) 3.2. Implement async correctly: Use async /await for all I/O operations, propagate CancellationToken 3.3. Apply constructor injection: Inject all dependencies via primary constructors 3.4. Validate at boundaries: Check inputs at application layer entry points, trust internal calls 3.5. Encapsulate business rules: Place all domain logic in aggregate methods, not services

  1. Testing (Required)

Write tests following these guidelines:

4.1. Apply naming convention: Use MethodName_Condition_ExpectedResult pattern 4.2. Structure with AAA: Organize tests into Arrange, Act, Assert sections 4.3. Test domain invariants: Cover all business rules with unit tests 4.4. Verify events: Assert that correct domain events are raised

[Fact] public void CalculateTotal_WithDiscount_ReturnsReducedAmount() { // Arrange var order = new Order(); order.ApplyDiscount(0.1m);

// Act
var total = order.CalculateTotal();

// Assert
Assert.Equal(90m, total);

}

Core Principles

Domain-Driven Design

Concept Purpose

Ubiquitous Language Consistent business terminology across code

Bounded Contexts Clear service boundaries

Aggregates Transactional consistency boundaries

Domain Events Capture business-significant occurrences

Rich Domain Models Business logic in domain, not services

SOLID Principles

  • SRP: One reason to change per class

  • OCP: Open for extension, closed for modification

  • LSP: Subtypes substitutable for base types

  • ISP: No forced dependency on unused methods

  • DIP: Depend on abstractions

C# Conventions

Naming:

  • PascalCase: Types, methods, public members, properties

  • camelCase: Private fields, local variables

  • Prefix interfaces with I (e.g., IUserService )

Formatting:

  • File-scoped namespaces

  • Newline before opening braces

  • Pattern matching and switch expressions preferred

  • Use nameof over string literals

Nullability:

  • Enable nullable reference types

  • Use is null / is not null (not == null )

  • Validate at entry points, trust annotations internally

Layer Responsibilities

Examples ordered by complexity (Easy → Medium → Hard):

// Aggregate root with encapsulated business logic public class Order : AggregateRoot { private readonly List<OrderLine> _lines = [];

public IReadOnlyCollection&#x3C;OrderLine> Lines => _lines.AsReadOnly();

public void AddLine(Product product, int quantity)
{
    if (quantity &#x3C;= 0)
        throw new DomainException("Quantity must be positive");

    _lines.Add(new OrderLine(product, quantity));
    AddDomainEvent(new OrderLineAddedEvent(Id, product.Id, quantity));
}

}

// Repository implementation with EF Core public class OrderRepository(AppDbContext db) : IOrderRepository { public async Task<Order?> GetByIdAsync(Guid id, CancellationToken ct) => await db.Orders .Include(o => o.Lines) .FirstOrDefaultAsync(o => o.Id == id, ct);

public async Task SaveAsync(Order order, CancellationToken ct)
{
    db.Orders.Update(order);
    await db.SaveChangesAsync(ct);
}

}

// Application service orchestrates domain operations public class OrderService( IOrderRepository orders, IProductRepository products, IEventPublisher events) { public async Task<OrderDto> AddLineAsync( Guid orderId, AddLineCommand command, CancellationToken ct = default) { // Validate input at boundary ArgumentNullException.ThrowIfNull(command);

    var order = await orders.GetByIdAsync(orderId, ct)
        ?? throw new NotFoundException($"Order {orderId} not found");

    var product = await products.GetByIdAsync(command.ProductId, ct)
        ?? throw new NotFoundException($"Product {command.ProductId} not found");

    // Execute domain logic (business rules in aggregate)
    order.AddLine(product, command.Quantity);

    // Persist and publish events
    await orders.SaveAsync(order, ct);
    await events.PublishAsync(order.DomainEvents, ct);

    return order.ToDto();
}

}

REST API Patterns

var orders = app.MapGroup("/api/orders") .WithTags("Orders") .RequireAuthorization();

orders.MapPost("/{orderId:guid}/lines", async ( Guid orderId, AddLineCommand command, OrderService service, CancellationToken ct) => { var result = await service.AddLineAsync(orderId, command, ct); return Results.Ok(result); }) .WithName("AddOrderLine") .Produces<OrderDto>() .ProducesProblem(StatusCodes.Status404NotFound);

[ApiController] [Route("api/[controller]")] public class OrdersController(OrderService orderService) : ControllerBase { /// <summary> /// Adds a line item to an existing order. /// </summary> [HttpPost("{orderId:guid}/lines")] [ProducesResponseType<OrderDto>(StatusCodes.Status200OK)] [ProducesResponseType<ProblemDetails>(StatusCodes.Status404NotFound)] public async Task<IActionResult> AddLine( Guid orderId, AddLineCommand command, CancellationToken ct) { var result = await orderService.AddLineAsync(orderId, command, ct); return Ok(result); } }

Complexity Limits

  • Maximum 50 lines per method (excluding blank lines and comments)

  • Cyclomatic complexity <10 per method

  • Maximum 7 dependencies per class (constructor parameters)

  • Aggregate size <1MB serialized

  • Collection properties limited to 1000 items maximum

Code Quality Standards

  • All public APIs must have XML documentation

  • No compiler warnings in production code

  • Nullable reference types enabled and enforced

  • No magic strings - use constants or nameof()

<security_constraints>

Input Validation

  • Validate all external input at application layer boundaries

  • Use FluentValidation or Data Annotations for request validation

  • Sanitize string inputs to prevent injection attacks

  • Validate GUIDs and IDs before database queries

Data Protection

  • Never log sensitive data (passwords, tokens, PII)

  • Use parameterized queries exclusively (EF Core handles this)

  • Implement proper authorization checks before data access

  • Hash passwords using BCrypt or Argon2, never store plaintext

API Security

  • Require authentication on all endpoints except explicitly public ones

  • Implement rate limiting on public endpoints

  • Validate JWT tokens with proper issuer and audience checks

  • Use HTTPS exclusively in production </security_constraints>

<success_criteria>

Code Quality Gates

  • All unit tests pass (0 failures)

  • Domain layer test coverage >= 90%

  • Application layer test coverage >= 85%

  • No SonarQube blocker or critical issues

  • No security vulnerabilities in dependency scan

Architectural Compliance

  • Domain layer has zero infrastructure dependencies

  • All aggregate modifications go through aggregate root methods

  • No business logic in controllers or infrastructure layer

  • All async operations use CancellationToken

Review Checklist

  • SOLID principles applied correctly

  • Aggregate boundaries maintain consistency

  • Domain events capture all significant state changes

  • Error handling follows ProblemDetails (RFC 7807)

  • Tests follow MethodName_Condition_ExpectedResult naming </success_criteria>

Reference Documentation

For detailed patterns and checklists, see:

  • DDD Patterns: Aggregate design, domain events, specifications

  • API Patterns: Validation, error handling, versioning, documentation

  • Testing Patterns: Test categories, mocking strategies, coverage requirements

Quick Reference

Monetary Values

  • Use decimal for all financial calculations

  • Implement currency-aware value objects

  • Handle rounding per financial standards

  • Maintain precision through calculation chains

Error Handling

// Global exception handler middleware app.UseExceptionHandler(error => error.Run(async context => { var exception = context.Features.Get<IExceptionHandlerFeature>()?.Error;

var problem = exception switch
{
    NotFoundException e => new ProblemDetails
    {
        Status = 404,
        Title = "Not Found",
        Detail = e.Message
    },
    DomainException e => new ProblemDetails
    {
        Status = 400,
        Title = "Business Rule Violation",
        Detail = e.Message
    },
    _ => new ProblemDetails
    {
        Status = 500,
        Title = "Internal Server Error"
    }
};

context.Response.StatusCode = problem.Status ?? 500;
await context.Response.WriteAsJsonAsync(problem);

}));

Dependency Injection Setup

// Program.cs builder.Services.AddScoped<IOrderRepository, OrderRepository>(); builder.Services.AddScoped<OrderService>(); builder.Services.AddDbContext<AppDbContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("Default")));

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

maui-blazor-development

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

storybook

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

react-typescript

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

atomic-design

No summary provided by upstream source.

Repository SourceNeeds Review