Instruction file imported from Yocheved4427/AI-Architecture (
.github/instructions/repositories.instructions.md). Copyright stays with the author.
Repository Layer Guidelines
Project: Repositories/
Contains ApiShopContext (EF Core DbContext, auto-generated by EF Core Power Tools) and all repository classes.
File Naming Quirk
Several files have invisible Unicode RTL mark characters prepended (e.g. IProductsRepository.cs). Do not rename them. Always search by content, not filename.
Rules
- Every repository must implement its corresponding
IXxxRepositoryinterface — never call a concrete class from a service. - All queries are async — use
async Task<T>withawait. Never call.Resultor.Wait(). - Use
Include()for eager-loading navigation properties (e.g.Include(p => p.Category)). - Filtering belongs in the repository; business decisions belong in the service.
ApiShopContextis auto-generated — add onlyDbSet<T>for new entities; do not alterOnModelCreatingmanually; usepartial classextensions if needed.
Adding a New Repository
Repositories/
ISupplierRepository.cs ← interface
SupplierRepository.cs ← implementation (inject ApiShopContext via constructor)
Interface pattern:
using Entities;
namespace Repositories
{
public interface ISupplierRepository
{
Task<IEnumerable<Supplier>> GetSuppliers();
Task<Supplier?> GetSupplier(int id);
Task<Supplier> AddSupplier(Supplier supplier);
Task<Supplier?> UpdateSupplier(int id, Supplier supplier);
Task<bool> DeleteSupplier(int id);
}
}
Implementation pattern:
using Entities;
using Microsoft.EntityFrameworkCore;
namespace Repositories
{
public class SupplierRepository : ISupplierRepository
{
public readonly ApiShopContext _context;
public SupplierRepository(ApiShopContext context) => _context = context;
public async Task<IEnumerable<Supplier>> GetSuppliers() =>
await _context.Suppliers.ToListAsync();
public async Task<Supplier?> GetSupplier(int id) =>
await _context.Suppliers.FindAsync(id);
public async Task<Supplier> AddSupplier(Supplier supplier)
{
_context.Suppliers.Add(supplier);
await _context.SaveChangesAsync();
return supplier;
}
public async Task<Supplier?> UpdateSupplier(int id, Supplier supplier)
{
var existing = await _context.Suppliers.FindAsync(id);
if (existing == null) return null;
// copy properties
await _context.SaveChangesAsync();
return existing;
}
public async Task<bool> DeleteSupplier(int id)
{
var existing = await _context.Suppliers.FindAsync(id);
if (existing == null) return false;
_context.Suppliers.Remove(existing);
await _context.SaveChangesAsync();
return true;
}
}
}
- Register in
Program.cs:builder.Services.AddScoped<ISupplierRepository, SupplierRepository>(); - Add
DbSet<Supplier>toApiShopContext.cs.
Testing Repositories
Unit tests use Moq + Moq.EntityFrameworkCore:
var mockContext = new Mock<ApiShopContext>(new DbContextOptions<ApiShopContext>());
mockContext.Setup(x => x.Products).ReturnsDbSet(productsList);
var repo = new ProductsRepository(mockContext.Object);
Integration tests use DatabaseFixture (SQL Server, srv2\pupils) — will fail without network access.