?? Master the Repository Pattern in .NET – Clean, Flexible & Scalable!

?? Master the Repository Pattern in .NET – Clean, Flexible & Scalable!

CRUD operations are the heart of software development, but handling them efficiently can be challenging. That’s where the Repository Pattern comes in!

It introduces a layer of abstraction between the business logic and data access, making your code cleaner, more maintainable, and easier to test.


?? Why Use the Repository Pattern?

? Abstraction – Separates business logic from database logic for better modularity. ? Testability – Enables unit testing by mocking repositories. ? Flexibility – Centralizes data access logic, promoting code reusability.


?? How Does It Work?

Let's break it down with a simple example:

?? 1?? Define a Repository Interface

public interface IRepository<T> where T : class
{
    Task<T> GetByIdAsync(int id);
    Task<IEnumerable<T>> GetAllAsync();
    Task AddAsync(T entity);
    Task UpdateAsync(T entity);
    Task DeleteAsync(int id);
}        

?? Defines CRUD operations for any entity.


?? 2?? Implement the Generic Repository

public class Repository<T> : IRepository<T> where T : class
{
    private readonly AppDbContext _context;
    private readonly DbSet<T> _dbSet;

    public Repository(AppDbContext context)
    {
        _context = context;
        _dbSet = context.Set<T>();
    }

    public async Task<T> GetByIdAsync(int id) => await _dbSet.FindAsync(id);

    public async Task<IEnumerable<T>> GetAllAsync() => await _dbSet.ToListAsync();

    public async Task AddAsync(T entity)
    {
        await _dbSet.AddAsync(entity);
        await _context.SaveChangesAsync();
    }

    public async Task UpdateAsync(T entity)
    {
        _dbSet.Update(entity);
        await _context.SaveChangesAsync();
    }

    public async Task DeleteAsync(int id)
    {
        var entity = await _dbSet.FindAsync(id);
        if (entity != null)
        {
            _dbSet.Remove(entity);
            await _context.SaveChangesAsync();
        }
    }
}        

?? Encapsulates CRUD operations for any entity.

?? Prevents code duplication.


public class ProductService
{
    private readonly IRepository<Product> _repository;

    public ProductService(IRepository<Product> repository)
    {
        _repository = repository;
    }

    public async Task<IEnumerable<Product>> GetProductsAsync()
    {
        return await _repository.GetAllAsync();
    }
}        

?? Keeps business logic separate from database logic.


? Advanced Features of the Repository Pattern

?? Flexible Querying with Func<IQueryable<T>>

public async Task<IEnumerable<T>> GetFilteredAsync(Func<IQueryable<T>, IQueryable<T>> filter)
{
    var query = filter(_dbSet);
    return await query.ToListAsync();
}        

?? Apply dynamic filtering & sorting at runtime!


?? Efficient Pagination

public async Task<(IEnumerable<T>, int)> GetPagedAsync(int page, int pageSize)
{
    var totalItems = await _dbSet.CountAsync();
    var items = await _dbSet.Skip((page - 1) * pageSize).Take(pageSize).ToListAsync();
    return (items, totalItems);
}        

?? Reduces load by fetching data in chunks.


?? Using Cancellation Tokens for Performance

public async Task<IEnumerable<T>> GetAllAsync(CancellationToken cancellationToken)
{
    return await _dbSet.ToListAsync(cancellationToken);
}        

?? Improves responsiveness by allowing operation cancellations.

?? Common Misconception

Many think the Repository Pattern makes switching databases easy. While it helps with abstraction, database migration (e.g., SQL → NoSQL) usually requires significant changes in query logic.


?? Start Using the Repository Pattern Today!

? Cleaner & more maintainable code

? Easier unit testing

? Better separation of concerns

Demo URL: https://github.com/pareshpbhayani/RepositoryPatternDemo

#RepositoryPattern #DotNetCore #CSharp #EntityFramework #CleanArchitecture #BestPractices #CodeOptimization #DesignPatterns #UnitTesting ??

要查看或添加评论,请登录

Paresh Bhayani的更多文章

社区洞察