The Dependency Inversion Principle (DIP) states that high-level modules/classes should not depend on low-level modules/classes
The most important point you need to remember while developing real-time applications is always to keep the High-level and Low-level modules as loosely coupled as possible.
When one class is aware of the design and implementation of another class, it increases the risk that , any changes made to one class will disrupt the other class. Therefore, it is important to maintain loose coupling between high-level and low-level modules/classes. To achieve this, both classes should depend on abstractions rather than having direct knowledge of each other. If this concept is currently unclear do not worry. By the end of this article, you will have a clear understanding of this concept through examples.
First, we will see an example without following the Dependency Inversion Principle. Then, we will identify the problems of not following the Dependency Inversion Principle. Finally, we will rewrite the same example using the Dependency Inversion Principle so that you can easily understand this concept
Create a Console Application and then add the following class files.
EmpDal.cs
DataAccessFactory.cs
EmpBal.cs
The following class has one constructor used to create an instance of the EmployeeDataAccessLogic class. Here, within the constructor, we call the static GetEmployeeDataAccessObj() method on the DataAccessFactory class, which will return an instance of EmployeeDataAccessLogic.
We then initialize the _EmployeeDataAccessLogic property with the returned instance. Additionally, we have one method, GetEmployeeDetails, which calls the GetEmployeeDetails method on the EmpDal instance to retrieve the employee details by employee ID.
So now, as per Dependency Inversion Principle
According to the definition of the Dependency Inversion Principle a High-Level module should not depend on Low-level modules. Both should depend on the abstraction.
From the above example, we need to identify High-Level Module (class) and the Low-Level Module (class) in our example.
A High-Level Module is a module that always depends on other modules. So, in our example, the EmpBal class depends on the EmpDal class, so here, the EmpBal class is the high-level module, and the EmpDal class is the low-level module.
So, according to the first rule of the Dependency Inversion Principle in C#, the EmpBal class/module should not depend on the concrete EmpDal class/module. Instead, both classes should depend on an abstraction. However, in our example, the way we have implemented the code, the EmpBal depending on the EmpDal class, means that we are not following the first rule. In the later part of this article, I will modify the example to follow the Dependency Inversion Principle.
The second rule of the Dependency Inversion Principle states that Abstractions" should not depend on details. Details should depend on "abstractions"
Let us understand about abstraction Now
In the previous example the EmpBal and EmpDal are concrete classes, meaning we can create objects of them. That is means we are also not following the second rule of the Dependency Inversion Principle.
As per the Dependency Inversion Principle in C#, the EmpBal (High-Level Module) should not depend on the concrete EmpDal (Low-Level Module) class. Both classes should depend on Abstractions, meaning both classes should depend on an Interface or an Abstract Class.
Now, the question is what methods should be in interface or abstract class.
Now, let us create an interface to achieve this principle
Now, we will change the EmpBal class code as shown below
That’s it. We have implemented the Dependency Inversion Principle in our example using C# language where the High-Level module (EmpBal) and Low-Level module (EmpDal) depend on abstraction (IEmployeeDataAccess). Also, abstraction (IEmployeeDataAccess) does not depend on details (EmpDal), but details depend on abstraction.
Now run the program.
Output
No comments:
Post a Comment
Thank you for visiting my blog