Roadmap › 1. .NET › Step 11
SO

SOLID Principles with Examples

The five SOLID principles with bad-vs-good C# code, plus DRY, KISS, YAGNI, dependency injection and how SOLID shows up in ASP.NET Core.
Quick revision for interview day. Print it or save it as a PDF.

SOLID in one table

PrincipleSmellFix
SSingle ResponsibilityGod class, Manager/UtilsSplit by reason to change
OOpen/ClosedGrowing switch/if-else on typeStrategy/polymorphism + DI
LLiskov SubstitutionOverride throws NotSupportedException; is checksFix the hierarchy; use interfaces/composition
IInterface SegregationImplementers leave methods emptySplit into role interfaces
DDependency Inversionnew ConcreteService() inside logicInject an abstraction

DI lifetimes

Instance perUse for
Transientresolutionstateless, light
ScopedrequestDbContext, unit of work
Singletonappconfig, caches, thread-safe services

Never inject scoped into singleton → use IServiceScopeFactory.

Other principles

  • DRY — one source of truth for knowledge.
  • KISS — simplest thing that works.
  • YAGNI — don't build for imaginary futures.
  • SoC — separate UI / business / data.
  • Composition over inheritance.
  • Law of Demeter — no a.B.C.D chains.

Quick code: DIP + OCP

csharp
public interface IExporter { string Format { get; } byte[] Export(Report r); }
public class PdfExporter : IExporter { public string Format => "pdf"; public byte[] Export(Report r) => ...; }
public class ExcelExporter : IExporter { public string Format => "xlsx"; public byte[] Export(Report r) => ...; }
public class ExportService(IEnumerable<IExporter> exporters)
{
    public byte[] Run(Report r, string fmt) => exporters.Single(e => e.Format == fmt).Export(r);
}

One-liners to say in the interview

  • SRP: "A class should have one reason to change — one actor it serves."
  • OCP: "Add new behaviour by adding classes, not by editing tested ones."
  • LSP: "A subclass must work anywhere its base class is expected — no surprises."
  • ISP: "Don't force clients to depend on methods they don't use."
  • DIP: "High-level policy depends on abstractions; details plug in through DI."
  • Balance: "I apply SOLID where change is likely; for simple, stable code I keep it simple."