From wpf-dev-pack
Implements Repository pattern with Service Layer for .NET data access abstraction using interfaces, async methods, and DI. Use for separating data logic from business logic or testable layers.
How this skill is triggered — by the user, by Claude, or both
Slash command
/wpf-dev-pack:implementing-repository-patternsonnetThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
> **MVVM Framework Rule**: `.claude/rules/dotnet/wpf/mvvm-framework.md` 설정에 따라 코드 스타일이 결정됩니다.
MVVM Framework Rule:
.claude/rules/dotnet/wpf/mvvm-framework.md설정에 따라 코드 스타일이 결정됩니다. Prism 9 사용 시 → PRISM.md 참조
A guide for implementing the Repository pattern that abstracts the data access layer.
MyApp/
├── Program.cs
├── App.cs
├── Models/
│ └── User.cs
├── Repositories/
│ ├── IUserRepository.cs
│ └── UserRepository.cs
├── Services/
│ ├── IUserService.cs
│ └── UserService.cs
└── GlobalUsings.cs
namespace MyApp.Models;
public sealed record User(int Id, string Name, string Email);
namespace MyApp.Repositories;
public interface IUserRepository
{
Task<List<User>> GetAllAsync();
Task<User?> GetByIdAsync(int id);
Task AddAsync(User user);
Task UpdateAsync(User user);
Task DeleteAsync(int id);
}
namespace MyApp.Repositories;
public sealed class UserRepository : IUserRepository
{
private readonly List<User> _users = [];
public Task<List<User>> GetAllAsync()
{
return Task.FromResult(_users.ToList());
}
public Task<User?> GetByIdAsync(int id)
{
return Task.FromResult(_users.FirstOrDefault(u => u.Id == id));
}
public Task AddAsync(User user)
{
_users.Add(user);
return Task.CompletedTask;
}
public Task UpdateAsync(User user)
{
var index = _users.FindIndex(u => u.Id == user.Id);
if (index >= 0) _users[index] = user;
return Task.CompletedTask;
}
public Task DeleteAsync(int id)
{
_users.RemoveAll(u => u.Id == id);
return Task.CompletedTask;
}
}
namespace MyApp.Services;
public interface IUserService
{
Task<IReadOnlyList<User>> GetAllUsersAsync();
Task<User?> GetUserByIdAsync(int id);
}
namespace MyApp.Services;
public sealed class UserService(IUserRepository repository) : IUserService
{
private readonly IUserRepository _repository = repository;
public async Task<IReadOnlyList<User>> GetAllUsersAsync()
{
var users = await _repository.GetAllAsync();
return users.AsReadOnly();
}
public Task<User?> GetUserByIdAsync(int id)
{
return _repository.GetByIdAsync(id);
}
}
var host = Host.CreateDefaultBuilder(args)
.ConfigureServices(services =>
{
// Register Repository
services.AddSingleton<IUserRepository, UserRepository>();
// Register Service
services.AddSingleton<IUserService, UserService>();
services.AddSingleton<App>();
})
.Build();
public interface IRepository<T> where T : class
{
Task<List<T>> GetAllAsync();
Task<T?> GetByIdAsync(int id);
Task AddAsync(T entity);
Task UpdateAsync(T entity);
Task DeleteAsync(int id);
}
App (Presentation)
↓
Service Layer (Business Logic)
↓
Repository Layer (Data Access)
↓
Data Source (DB, API, File, etc.)
npx claudepluginhub christian289/dotnet-with-claudecode --plugin wpf-dev-packGenerates Repository interfaces and EF Core implementations per aggregate root, with query methods and Unit of Work integration for .NET DDD projects.
Provides .NET backend patterns for APIs, MCP servers, and enterprise apps: clean architecture, DI, EF Core, Dapper, Redis caching, IOptions config, and xUnit testing.
SOLID principles for C# 12/.NET 9. Files < 100 lines, interfaces separated, modular architecture. Contracts MANDATORY.