Claude-skill-registry implementing-repository-pattern
Implements the Repository pattern with Service Layer for data access abstraction in .NET. Use when separating data access logic from business logic or building testable data layers.
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/implementing-repository-pattern" ~/.claude/skills/majiayu000-claude-skill-registry-implementing-repository-pattern && rm -rf "$T"
manifest:
skills/data/implementing-repository-pattern/SKILL.mdsource content
.NET Repository Pattern
A guide for implementing the Repository pattern that abstracts the data access layer.
1. Project Structure
MyApp/ ├── Program.cs ├── App.cs ├── Models/ │ └── User.cs ├── Repositories/ │ ├── IUserRepository.cs │ └── UserRepository.cs ├── Services/ │ ├── IUserService.cs │ └── UserService.cs └── GlobalUsings.cs
2. Model Definition
namespace MyApp.Models; public sealed record User(int Id, string Name, string Email);
3. Repository Layer
3.1 Interface
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); }
3.2 Implementation
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; } }
4. Service Layer
4.1 Interface
namespace MyApp.Services; public interface IUserService { Task<IReadOnlyList<User>> GetAllUsersAsync(); Task<User?> GetUserByIdAsync(int id); }
4.2 Implementation
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); } }
5. DI Registration
var host = Host.CreateDefaultBuilder(args) .ConfigureServices(services => { // Register Repository services.AddSingleton<IUserRepository, UserRepository>(); // Register Service services.AddSingleton<IUserService, UserService>(); services.AddSingleton<App>(); }) .Build();
6. Generic Repository (Optional)
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); }
7. Layer Structure
App (Presentation) ↓ Service Layer (Business Logic) ↓ Repository Layer (Data Access) ↓ Data Source (DB, API, File, etc.)
8. Core Principles
- Repository handles data access only
- Business logic goes in Service
- Abstract with interfaces for testability
- Use Constructor Injection for dependencies