SOLID Principles in .NET Core
SOLID principles are the foundation of clean architecture and design patterns in .NET Core applications. These principles help developers write scalable, maintainable, reusable, and testable code.
1. S — Single Responsibility Principle (SRP)
Definition: A class should have only one reason to change.
Alternative for: Large classes doing multiple jobs.
Bad Example:
public class UserService
{
public void RegisterUser() { }
public void SendEmail() { }
public void SaveToDatabase() { }
}
The class handles:
- User registration
- Email sending
- Database operations
Good Example:
public class UserService
{
public void RegisterUser() { }
}
public class EmailService
{
public void SendEmail() { }
}
public class UserRepository
{
public void Save() { }
}
Each class now has a single responsibility.
2. O — Open/Closed Principle (OCP)
Definition: Software entities should be open for extension but closed for modification.
Alternative for: Modifying existing code repeatedly.
Bad Example:
public class PaymentService
{
public void Pay(string type)
{
if(type == "Card")
{
}
else if(type == "UPI")
{
}
}
}
Good Example Using Strategy Pattern:
public interface IPayment
{
void Pay();
}
public class CardPayment : IPayment
{
public void Pay() { }
}
public class UpiPayment : IPayment
{
public void Pay() { }
}
Now new payment methods can be added without modifying old code.
3. L — Liskov Substitution Principle (LSP)
Definition: Derived classes should be replaceable with base classes without breaking behavior.
Alternative for: Incorrect inheritance usage.
Bad Example:
public class Bird
{
public virtual void Fly() { }
}
public class Ostrich : Bird
{
public override void Fly()
{
throw new Exception();
}
}
Ostrich cannot fly, so inheritance is wrong.
Good Example:
public interface IBird
{
}
public interface IFlyingBird
{
void Fly();
}
public class Sparrow : IFlyingBird
{
public void Fly() { }
}
public class Ostrich : IBird
{
}
4. I — Interface Segregation Principle (ISP)
Definition: Clients should not be forced to implement unused methods.
Alternative for: Fat interfaces.
Bad Example:
public interface IWorker
{
void Work();
void Eat();
}
Robot does not eat.
public class Robot : IWorker
{
public void Work() { }
public void Eat()
{
throw new Exception();
}
}
Good Example:
public interface IWork
{
void Work();
}
public interface IEat
{
void Eat();
}
public class Human : IWork, IEat
{
public void Work() { }
public void Eat() { }
}
public class Robot : IWork
{
public void Work() { }
}
5. D — Dependency Inversion Principle (DIP)
Definition: High-level modules should not depend on low-level modules. Both should depend on abstractions.
Alternative for: Tight coupling using new keyword.
Bad Example:
public class UserService
{
private EmailService emailService = new EmailService();
}
Good Example Using Dependency Injection:
public interface IEmailService
{
void Send();
}
public class EmailService : IEmailService
{
public void Send() { }
}
public class UserService
{
private readonly IEmailService _emailService;
public UserService(IEmailService emailService)
{
_emailService = emailService;
}
}
SOLID Principles and Related Design Patterns
| SOLID Principle | Common Design Patterns |
|---|---|
| SRP | Repository, Service Pattern |
| OCP | Strategy, Factory |
| LSP | Template Method |
| ISP | Adapter, Interface-based design |
| DIP | Dependency Injection, Mediator |
Conclusion
SOLID principles are the backbone of modern .NET Core architecture. Most design patterns are built using SOLID concepts.
- SRP → One class, one responsibility
- OCP → Extend without modifying
- LSP → Correct inheritance
- ISP → Small focused interfaces
- DIP → Depend on abstractions
Following SOLID principles makes applications:
- Easy to maintain
- Easy to test
- Scalable
- Reusable
- Cleaner architecture
Comments
Post a Comment