SOLID Design Principles in C# with helpful examples
 
                Introduction
  Hi readers! This time, I have brought the new C# topic on ‘Solid Design
  Principles in C#’ along with some valuable examples.
  Here, we will be discussing ‘C# Solid Design Principles’ along with some valuable examples that are based on various .net
  applications including Web API, ASP.NET MVC, and Console Applications.
  These C# design principles enable us to resolve most of the issues that are
  created in software design. These C# design principles facilitate us with
  different methods to shift the tightly bonded code between the software
  components which gives rise to software designs more acceptable, adaptable,
  and maintainable.
  This article will be more helpful for beginners as well as experienced
  professional developers who wish to learn more and solve errors in C# SOLID
  Design Principles.
Why do we need SOLID Design Principles?
  Often, the C# developers,
  commence developing applications
  utilizing their experience and proficiency. But over time, the applications
  might need changes or improvements. Hence, we have to modify the application
  design for each of the modification requirements or a new request type. The
  required modifications may need a lot of effort as well as time, even for
  simpler smaller tasks.
  The above issues can be solved and the beginners as well as professional c#
  developers who wish to learn how to develop good valuable software utilizing
  SOLID Design Principles in C# within a short duration.
  What do you mean by SOLID Design Principles in C#?
  The C# SOLID Principles are generally utilized to control most of the software
  design difficulties that are usually experienced in our day-to-day
  programming. These Solid principles are furnished with some specific tools
  that make the software designs more acceptable and easily maintainable.
  What is the main reason behind most of the unsuccessful applications?
Find below some main reasons for the failure of many software.
- 
    Applying more functionalities to some classes, even though those
 functionalities are not related to the respective classes.
- 
    Enforcing Tight coupling between these classes. The changes in one of the
 interdependent classes ultimately affect other classes.
How do solve the C# application issues?
- A developer needs to follow the Principles of SOLID C# design.
- 
    We need to use the accurate architecture (i.e. MVC, MVP, Layered, and
 3-tier, etc.) as per the project need.
- 
    Again we have to select the precise Design Patterns as per the project
 provisions.
SOLID Acronym
  In OOP (Object Oriented Programming), SOLID is an acronym for five crucial
    C# design principles, which was introduced by Michael Feathers.
- S for the Single Responsibility Principle (SRP).
- O for the Open-Closed Principle (OSP).
- L for the Liskov Substitution Principle (LSP)
- I for the Interface Segregation Principle (ISP).
- D for Dependency Inversion Principle (DIP)
Let’s have a look at these 5 C# principles.
1. Single Responsibility Principle (SRP)
  This principle indicates that ‘A class Needs to have only one reason to get
  altered’. This definition comes from Robert C. Martin’s ‘Agile
  Software Development
  book which is based on the C# version along with Patterns, Principles, and
  Practices.  
  In layman terminology, it states that a class should not come with multiple
  responsibilities as well as a single responsibility that need not be spread
  across various classes or combined with other responsibilities. The reason is
  that the more modifications are expected in the future, the more changes the
  class has to apply.
Explanation
  Single Responsibility Principle is the first principle among five SOLID
  principles which enable
  developers
  as they write code or design an app.
  In simple terms, a module or class needs to possess a very small area of
  responsibility in the whole application. Or as it indicates that, a class or
  module needs no more than one reason to modify.
  If a class contains only a single responsibility, it will be very robust. It’s
  easier to validate it’s working as per the logic explained. And it’s much
  easier to alter in class as it possesses single responsibility. In this
  responsibility principle, the Classes,  modules, and software components
  that possess only single responsibility are much easier to elaborate,
  implement and realize than the ones that provide the right solution for
  everything.
  This also decreases the number of bugs and increases the development speed and
  most significantly reduces the work burden of developers.
Example
  Let’s consider a real-time operation of a car Garage service station.
  Generally, it contains 3 major functions such as open gate, close gate, and
  provide service.
Working Example:
2. Open Closed Principle (OCP)
  Most of the
  C# software
  entities like classes, functions, modules, and many more need to be open for
  extension, but closed for alteration.
  Bertrand Meyer in the ‘open/closed‘ principle in his popular book
  ‘Object-Oriented Software Construction‘
Explanation
  This principle proposes that the class needs to be extended easily without
  changing its core performances.
  The
  software/app
  needs to be flexible to get altered. The way how modification management is
  applied in a system has a crucial effect on the achievement of that
  app/software. The OCP indicates that the aspects of the system can be expanded
  without modifying its current performance.
  It means, New features need to be enforced by utilizing the new code, but not
  by modifying the current code. The main advantage of implementing OCP is that
  it potentially simplifies code maintenance and lowers the risk of breaking the
  current implementation.
Example
  Let’s consider an example of bank accounts such as regular savings,
  corporate,   salary savings, etc. for various customers. As for
  every type of customer, with different rates of interest, and different rules,
  the following code violates the principle of OCP if the bank initiates a new
  type of Account. Hence, the required code changes this method to add a new
  type of account.
  We can incorporate OCP through the interface, abstract methods, abstract
  class, and virtual methods when you wish to expand functionality. I have
  utilized the interface here for example only you can proceed as per your need.
  This can resolve the issue of change of class and by expanding the interface,
  we can augment functionality ultimately.
  Overall, the above code is enforcing both OCP and SRP principles, since each
  class is performing a single task and we are not changing classes and only
  performing an extension.
3. Liskov Substitution Principle (LSP)
  Robert C. Martin states that functions that utilize references or pointers to
  the base classes must utilize the derived class objects without having an idea
  about it.
  The LSP is a right definition of a subtyping association, named strong
  behavioral subtyping, which was originally introduced in 1987 by Barbara
  Liskov in the ‘Data abstraction and hierarchy’ conference keynote.
Explanation
  LSP states that the child classes need to be flawlessly exchangeable for their
  parent class. If class C is obtained from P then C should be exchangeable for
  P.
We can test through LSP whether inheritance is adequate or not in our code.
  LSP is an essential principle of C# SOLID Principles and asserts that if a
  module or program is utilizing a base class then the derived class needs to
  expand its base class without altering its actual performance.
Example
Let’s consider the following codes where LSP is obeyed perfectly
4. Interface Segregation Principle (ISP)
  We can’t enforce any client to apply methods that it does not utilize, and the
  contracts need to be broken down into thin ones.
  However, the ISP was first utilized and defined by Robert C. Martin at the
  time of guiding for Xerox.
  ISP is employed to get the design issues of the application resolved. When the
  whole tasks are accomplished by a single class or we can say, one class is
  utilized in most of the
  application
  classes then it turns into a fat class with the extra burden.
  Inheritance
  of such class results in getting the sharing procedures that are not relevant
  to originated classes but it’s available in the base class so that will be
  able to inherit in the
  originated class.
  Through ISP, we can create different interfaces for each requirement or
  operation rather than possessing a single class to accomplish similar work.
Example
In the following code, ISP is cracked with the following example:
5. Dependency Inversion Principle (DIP)
  This principle explains the reliances among elements. The DIP is defined well
  by Robert C. Martin as follows:
- 
    High-level modules need not depend on lower-level modules. So, both need to
 depend on abstractions.
- 
    Abstractions need not rely on detailed information, whereas detailed
 information needs to depend on abstractions.
Explanation
  This principle states that higher-level modules need to rely on abstraction,
  not on the detailed information of lower-level modules. It means a tight bond
  among components of software should not be available and to skip that, the
  components need to rely on abstraction.
  The terms Inversion of Control (IoC) and Dependency
  Injection
  (DI) are commonly utilized interchangeably to explain the equivalent design
  structure. The structure was called IoC in the beginning, but Martin Fowler,
  the enterprise software designer anticipated the name as DI since most of the
  frameworks or runtime reverse the control in some path and he was keen to know
  which characteristic of control was being reversed.
  IoC is the right method to apply the DIP in the application of C#. Inversion
  of control can be applied through either an interface or an abstract class.
  The Dip rule states that the lower-level entities need to join the agreement
  to a single interface and the higher-level entities utilize only entities that
  are carrying out the interface. This procedure reduces the dependency between
  the different entities.
Example
  In the following code, we have enforced DIP through IoC utilizing an injection
  developer. There are multiple approaches to enforcing Dependency injection.
  Here, In the following example, I have utilized interface as a reference, but
  anybody can utilize an abstract class or interface as per necessity.
  We utilize injection through builder but you inject the reliance into the
  constructor (constructor injection) of class, method (Method Injection), set
  property (Setter Injection), events, fields, index properties, and practically
  any members of the public class.
  DI is a software application design structure that enables us to get developed
  loosely bonded code. Through DI, we could lower the tight bonding between
  software elements. DI also enables us to better achievement of future
  modifications and other complications in our software application. The
  objective of DI is to enable code sustainability.
  What are the Advantages of using SOLID Design Principles in C#?
  We will have the following benefits of utilizing C#  SOLID Design
  Principles.
- Attain the lowering in the complicatedness of the code
- 
    Improve the readability, maintenance, and extensibility with lowering of
 error and incorporation Reusability
- Obtain Better testability and lower tight bonding.
More about advantages
  While the developers are designing and developing any app/software, then you
  need to assess the following points.
Flexibility and extensibility
  Nowadays flexibility and extensibility are very much necessary for the
  development of enterprise applications. So we need to design the application
  in such a method that it needs to be flexible so that it can be modified to
  work in various methods and expandable so that we can incorporate new
  characteristics easily with lesser changes.
Maintainability:
  Maintaining the software application is the greatest challenge for the
  Industry. Day to day, the hen volume of business increases for the
  organization and as the business rises you have to improve the software with
  new alterations. So you have to design and develop the software in such a
  manner that it could receive future modifications with the least effort and
  without any single issues.
Test-Driven Development (TDD)
  TDD is one of the most crucial key characteristics when you wish to design and
  develop a specific application that is large-scale level. We have to design
  the software application in such a manner that we could test every individual
  performance for better utility and future provision.
Parallel Development:
  The Parallel Development of a software application is one of the most
  significant key elements. As we realize it is not feasible to retain the whole
  development team performing on a similar module at the same moment. So we need
  to design the software in such a manner that multiple teams can perform on
  multiple modules at a time.
Conclusion
  The above 5 C# SOLID design principles are most valuable for Object Oriented
  design. Most of the above principles implicated include a layer of abstraction
  among classes that would differently rely on each other, thus making a loose
  coupling bonding which outcomes in less rigorous and fragile code. Often, it
  is recommended to keep the above solid principles in mind when writing new
  code.


 
                       
                       
                       
                       
                      