Roadmap › SOLID Principles with Examples › Module: S and O
Lessons in this course (8)

1. S — Single Responsibility Principle

Basic★ Must knowLesson 1 of 8

"A class should have one, and only one, reason to change." — Robert C. Martin

"Reason to change" = one actor or stakeholder. A class that formats invoices and saves them and emails them changes when finance, DBAs or the email provider change.

csharp
// ❌ Violates SRP — three reasons to change
public class InvoiceService
{
    public decimal Calculate(Invoice i) => i.Lines.Sum(l => l.Qty * l.Price) * 1.18m;
    public void Save(Invoice i) { using var c = new SqlConnection("..."); /* INSERT ... */ }
    public void Email(Invoice i) { var smtp = new SmtpClient("smtp.example.com"); /* ... */ }
}

// ✅ One responsibility each
public class InvoiceCalculator { public decimal Total(Invoice i) => i.Lines.Sum(l => l.Qty * l.Price) * 1.18m; }
public interface IInvoiceRepository { Task SaveAsync(Invoice i); }
public interface IInvoiceSender { Task SendAsync(Invoice i); }

public class InvoiceWorkflow(InvoiceCalculator calc, IInvoiceRepository repo, IInvoiceSender sender)
{
    public async Task CompleteAsync(Invoice i)
    {
        i.Total = calc.Total(i);
        await repo.SaveAsync(i);
        await sender.SendAsync(i);
    }
}

Interview tip: SRP doesn't mean "one method per class". It means one cohesive job. Controllers that only orchestrate are fine.