Abstraction
Abstraction hides complexity behind simplified models — you call TransferMoney without knowing ledger SQL details.
Introduction
Abstraction hides complexity behind simplified models — you call TransferMoney without knowing ledger SQL details. Abstract classes and interfaces are C# abstraction tools; higher-level patterns include repository, facade, and gateway abstractions over HTTP and databases.
Interviewers distinguish abstraction from encapsulation: abstraction is about what is exposed conceptually; encapsulation is about hiding how internally. Both appear in layered architecture discussions.
This lesson builds abstract repositories and services mirroring real ASP.NET Core layering.
The story
A SaaS CRM registers new customers without knowing whether they are stored in PostgreSQL, SQL Server, or an in-memory database during demos. The CustomerService depends on ICustomerRepository — an abstraction — while an infrastructure project supplies the EF Core implementation.
That separation is what lets teams test business logic with a fake repository and swap databases without touching registration code.
Understanding the topic
Key concepts
- Abstraction focuses on essential behavior, hides implementation.
- abstract class defines partial contract + shared code.
- interface defines pure contract.
- Layered architecture abstracts data access from business logic.
- Dependency inversion: high-level modules depend on abstractions.
- Leaky abstraction exposes internals — avoid in public APIs.
Step-by-step explanation
- Define IRepository
with domain-meaningful methods. - Business services depend on IRepository, not SqlConnection.
- Infrastructure project implements interfaces with EF Core.
- Abstract class TemplateMethod defines algorithm skeleton.
- Consumers see simplified API; complexity in implementation.
- Tests substitute fake implementations of abstractions.
Practical code example
Abstract repository contract decoupling domain from EF Core:
namespace TechLearningPro.Abstraction;public interface ICustomerRepository{Task<Customer?> FindByIdAsync(Guid id, CancellationToken ct);Task AddAsync(Customer customer, CancellationToken ct);Task SaveChangesAsync(CancellationToken ct);}public sealed record Customer(Guid Id, string Email, string Name);public sealed class CustomerService(ICustomerRepository repo){public async Task RegisterAsync(string email, string name, CancellationToken ct){var customer = new Customer(Guid.NewGuid(), email.Trim().ToLowerInvariant(), name);await repo.AddAsync(customer, ct);await repo.SaveChangesAsync(ct);}}
Line-by-line code explanation
interface ICustomerRepositorydeclares persistence operations without mentioning SQL or EF.Task<Customer?> FindByIdAsync(...)returns a nullable customer — honest about missing records.Task AddAsync(...)andTask SaveChangesAsync(...)separate insert from commit.sealed record Customer(...)is a lightweight domain model passed across layers.CustomerService(ICustomerRepository repo)depends on the abstraction, not a concrete database class.RegisterAsync(string email, string name, ...)orchestrates customer creation at the application layer.email.Trim().ToLowerInvariant()normalizes email before persistence.new Customer(Guid.NewGuid(), ...)creates the entity with a fresh identifier.await repo.AddAsync(customer, ct)stages the insert through the repository abstraction.await repo.SaveChangesAsync(ct)commits the unit of work transactionally.
Key takeaway: CustomerService knows nothing about SQL — only ICustomerRepository abstraction. EF implementation lives in Infrastructure layer.
Real-world use
Where you'll use this in production
- Repository pattern over EF Core DbSets.
- Payment gateway abstracting Stripe vs Adyen.
- Cloud storage abstracting Azure Blob vs S3.
- Logging abstracted via ILogger interface.
Best practices
- Abstractions shaped by client needs, not database tables.
- Keep interfaces small — Interface Segregation Principle.
- Place interfaces in domain/application layer.
- Avoid leaking ORM types through abstractions.
- Name abstractions by capability not technology.
Common mistakes
- IRepository
with 30 CRUD methods nobody uses. - Returning IQueryable from repository — leaks LINQ provider.
- Abstract class with only abstract members — use interface.
- Business logic in repository implementation.
Advanced interview questions
Q1BeginnerAbstraction vs encapsulation?
Q2BeginnerWhy IRepository?
Q3Intermediateabstract class when?
Q4IntermediateLeaky abstraction example?
Q5AdvancedDesign abstraction for file storage usable in tests without cloud.
Summary
Abstraction simplifies complex systems via focused contracts. Interfaces and abstract classes define what, not how. Layered apps depend on abstractions, not concretions. Repository and gateway patterns are daily abstraction tools. Next: interfaces in depth.