Comprehensive .NET development guidelines covering DDD, SOLID principles, ASP.NET Core REST APIs, and C# best practices. Use when working with: (1) C# code files (.cs), (2) .NET project files (.csproj, .sln), (3) ASP.NET Core applications, (4) Domain-Driven Design implementations, (5) REST API development, (6) Entity Framework Core, (7) Unit/integration testing in .NET. Specifically triggers for: classes inheriting AggregateRoot/Entity, services with IRepository dependencies, controllers inheriting ControllerBase, or files in Domain/Application/Infrastructure folders.
/plugin marketplace add iButters/ClaudeCodePlugins/plugin install dotnet-development@claude-code-pluginsThis skill is limited to using the following tools:
Execute this process for any .NET implementation task:
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
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
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
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);
}
</workflow>
| 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 |
Naming:
I (e.g., IUserService)Formatting:
nameof over string literalsNullability:
is null / is not null (not == null)Examples ordered by complexity (Easy → Medium → Hard):
<example name="domain-layer" complexity="easy"> ### Domain Layer// Aggregate root with encapsulated business logic
public class Order : AggregateRoot
{
private readonly List<OrderLine> _lines = [];
public IReadOnlyCollection<OrderLine> Lines => _lines.AsReadOnly();
public void AddLine(Product product, int quantity)
{
if (quantity <= 0)
throw new DomainException("Quantity must be positive");
_lines.Add(new OrderLine(product, quantity));
AddDomainEvent(new OrderLineAddedEvent(Id, product.Id, quantity));
}
}
</example>
<example name="infrastructure-layer" complexity="medium">
### Infrastructure Layer
// 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);
}
}
</example>
<example name="application-layer" complexity="hard">
### Application Layer
// 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();
}
}
</example>
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);
</example>
<example name="controller-api" complexity="hard">
### Controller-Based API
[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);
}
}
</example>
<constraints>
## Performance Constraints
- Domain operations: <100ms execution time
- Repository calls: <500ms including database round-trip
- API response time: <200ms for simple queries, <1000ms for complex aggregations
<security_constraints>
<success_criteria>
For detailed patterns and checklists, see:
decimal for all financial calculations// 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);
}));
// Program.cs
builder.Services.AddScoped<IOrderRepository, OrderRepository>();
builder.Services.AddScoped<OrderService>();
builder.Services.AddDbContext<AppDbContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("Default")));
This skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.
This skill should be used when the user asks to "create a slash command", "add a command", "write a custom command", "define command arguments", "use command frontmatter", "organize commands", "create command with file references", "interactive command", "use AskUserQuestion in command", or needs guidance on slash command structure, YAML frontmatter fields, dynamic arguments, bash execution in commands, user interaction patterns, or command development best practices for Claude Code.
This skill should be used when the user asks to "create a hook", "add a PreToolUse/PostToolUse/Stop hook", "validate tool use", "implement prompt-based hooks", "use ${CLAUDE_PLUGIN_ROOT}", "set up event-driven automation", "block dangerous commands", or mentions hook events (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification). Provides comprehensive guidance for creating and implementing Claude Code plugin hooks with focus on advanced prompt-based hooks API.