Use when idiomatic C# and .NET patterns, conventions, dependency injection, async/await, and best practices for building robust, maintainable .NET applications. Only for C#/.NET — not for other languages. Triggers on \"dotnet-patterns\", \"dotnet patterns\", \"patterns\".
Installs into .claude/skills of the current project.
Are you the author of Dotnet Patterns?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/majinmagros-dotnet-patterns)
---
name: dotnet-patterns
description: "Use when idiomatic C# and .NET patterns, conventions, dependency injection, async/await, and best practices for building robust, maintainable .NET applications. Only for C#/.NET — not for other languages. Triggers on \"dotnet-patterns\", \"dotnet patterns\", \"patterns\"."
metadata:
origin: ECC
---
# .NET Development Patterns
Idiomatic C# and .NET patterns for building robust, performant, and maintainable applications.
## When to Activate
- Writing new C# code
- Reviewing C# code
- Refactoring existing .NET applications
- Designing service architectures with ASP.NET Core
## Core Principles
### 1. Prefer Immutability
Use records and init-only properties for data models. Mutability should be an explicit, justified choice.
```csharp
// Good: Immutable value object
public sealed record Money(decimal Amount, string Currency);
// Good: Immutable DTO with init setters
public sealed class CreateOrderRequest
{
public required string CustomerId { get; init; }
public required IReadOnlyList<OrderItem> Items { get; init; }
}
// Bad: Mutable model with public setters
public class Order
{
public string CustomerId { get; set; }
public List<OrderItem> Items { get; set; }
}
```
### 2. Explicit Over Implicit
Be clear about nullability, access modifiers, and intent.
```csharp
// Good: Explicit access modifiers and nullability
public sealed class UserService
{
private readonly IUserRepository _repository;
private readonly ILogger<UserService> _logger;
public UserService(IUserRepository repository, ILogger<UserService> logger)
{
_repository = repository ?? throw new ArgumentNullException(nameof(repository));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public async Task<User?> FindByIdAsync(Guid id, CancellationToken cancellationToken)
{
return await _repository.FindByIdAsync(id, cancellationToken);
}
}