Use when working with .cs files, .NET projects, implementing C# features, advising on C#/.NET architecture and patterns, or answering questions about C#/.NET development. Covers async patterns, dependency injection, LINQ, and testing conventions.
/plugin marketplace add jkappers/claude-code-software-delivery-plugin/plugin install jkappers-software-delivery-pack-claude@jkappers/claude-code-software-delivery-pluginThis skill inherits all available tools. When active, it can use any tool Claude has access to.
Apply these patterns when working with C# code. When both developing-csharp and testing-xunit apply, testing-xunit takes precedence in test files.
| Element | Convention | Example |
|---|---|---|
| Classes, Structs | PascalCase | UserService |
| Interfaces | IPascalCase | IUserRepository |
| Methods, Properties | PascalCase | GetUserById |
| Private fields | _camelCase | _userRepository |
| Parameters, locals | camelCase | userId |
| Async methods | PascalCase + Async | GetUserByIdAsync |
src/
├── MyApp.Api/Controllers/
├── MyApp.Core/Entities/, Interfaces/, Services/
├── MyApp.Infrastructure/Repositories/, Data/
tests/
├── MyApp.UnitTests/
├── MyApp.IntegrationTests/
Register services in Program.cs:
builder.Services.AddScoped<IUserRepository, UserRepository>();
builder.Services.AddSingleton<ICacheService, RedisCacheService>();
builder.Services.AddTransient<IEmailSender, SmtpEmailSender>();
| Lifetime | Use For |
|---|---|
| Singleton | Shared state, caches, configuration |
| Scoped | Per-request state, DbContext, repositories |
| Transient | Stateless services, lightweight operations |
Inject via constructor:
public class UserService : IUserService
{
private readonly IUserRepository _userRepository;
private readonly ILogger<UserService> _logger;
public UserService(IUserRepository userRepository, ILogger<UserService> logger)
{
_userRepository = userRepository;
_logger = logger;
}
}
Always use Async suffix. Always await or return the task. Use ConfigureAwait(false) in libraries. Support CancellationToken.
public async Task<User> GetUserAsync(int id, CancellationToken ct = default)
{
return await _context.Users.FirstOrDefaultAsync(u => u.Id == id, ct);
}
Do not use async void except for event handlers. Do not block with .Result or .Wait(). Do not ignore tasks with _ = ProcessAsync().
Prefer method syntax:
var activeUsers = users
.Where(u => u.IsActive)
.OrderBy(u => u.LastName)
.Select(u => new UserDto(u.Id, u.FullName))
.ToList();
Materialize once to avoid multiple enumeration:
var activeUsers = users.Where(u => u.IsActive).ToList();
var count = activeUsers.Count;
var first = activeUsers.First();
Use custom exception hierarchy:
public class DomainException : Exception { }
public class NotFoundException : DomainException { }
public class ValidationException : DomainException
{
public IReadOnlyList<string> Errors { get; }
}
Result pattern alternative:
public class Result<T>
{
public bool IsSuccess { get; }
public T? Value { get; }
public string? Error { get; }
public static Result<T> Success(T value) => new(value);
public static Result<T> Failure(string error) => new(error);
}
public class UserServiceTests
{
private readonly Mock<IUserRepository> _mockRepo;
private readonly UserService _sut;
public UserServiceTests()
{
_mockRepo = new Mock<IUserRepository>();
_sut = new UserService(_mockRepo.Object);
}
[Fact]
public async Task GetByIdAsync_WithValidId_ReturnsUser()
{
var expectedUser = new User { Id = 1, Name = "John" };
_mockRepo.Setup(r => r.GetByIdAsync(1)).ReturnsAsync(expectedUser);
var result = await _sut.GetByIdAsync(1);
Assert.NotNull(result);
Assert.Equal("John", result.Name);
}
}
public class AppDbContext : DbContext
{
public DbSet<User> Users => Set<User>();
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.ApplyConfigurationsFromAssembly(typeof(AppDbContext).Assembly);
}
}
Avoid the repository pattern with Entity Framework.
var for obvious typesreadonly fieldsrecord for DTOs: public record UserDto(int Id, string Name);using statements for disposable resources"" not string.Emptyint[] numbers = [1, 2, 3];Creating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems. Create original algorithmic art rather than copying existing artists' work to avoid copyright violations.
Applies Anthropic's official brand colors and typography to any sort of artifact that may benefit from having Anthropic's look-and-feel. Use it when brand colors or style guidelines, visual formatting, or company design standards apply.
Create beautiful visual art in .png and .pdf documents using design philosophy. You should use this skill when the user asks to create a poster, piece of art, design, or other static piece. Create original visual designs, never copying existing artists' work to avoid copyright violations.