So now it's a time to deal with our fifth and last principle of solid principle. guys up to this point, we know that we have an acronym solid, which is S o l ID, and now is the time for D which is dependency inversion principle. Now, before I proceed, I would like to clarify that this is dependency inversion principle, not dependency injection principle. dependency injection is a separate design pattern, which is using this principle, which is dependency inversion principle. In the same course, in futures after some videos, I'm going to cover dependency injection also in depth. But right now, what i'm talking is dependency inversion principle, which is the fifth and last principle of our solid principles.
Now, this principle is trying to tell you that objects should be loosely coupled. an injection should happen at runtime. Now, this is a strong and very, very, very important line to understand. And to understand this thing properly, I'm going back to my code once again. Now, we have a printing system class and we have printing system client to class, both the classes are having print method inside that and the sweet print methods are actually having two different logic. But same signature, which is coming from interface, I invoice printer.
Now, if you focus on our structure right now, we have so many classes inside this. And in all of these classes, we are following all the rules of solid. So all first four rules like single responsibility, and then open closed principle. And then let's go substitution principle interface segregation principle. We're following all four rules. Now I just want to focus on one of the class which is having an invoice printer.
This was the class which we created, I think in the first or second video. And this invoice printer class is focused on only one purpose, which is print, and they have a printing logic. Now, this is a trend, which is not associated with any of the printing systems. So let's say that I want to utilize this printing system inside this and based on that we are going to do the printing logic. In short, my invoice printer is going to use one of the printing system logic associated with that. To do this thing, I'm going to create a private variable.
So we are creating a private variable of type printing system. And I'm giving a name of this underscore print system. And when we do this thing, this is a private variable, which is going to associate with the constructor of this class. So I'm just going to create a constructor for this class, which is invoice printer associated with this. And we have a printing system kind of parameter inside that automatically is taken that and this printing system is assigned to underscore printing system. So this is what we have done inside this invoice printer.
And it is showing the incomplete activity because somewhere I think the printing system class is not having a public key over here. So let me add a public key for now. And now if I come back to this, it's not showing any issues. So this is my constructor and we have a private variable associated with this. Now this printing logic will go like this, that we are going to specify that underscore print system dot and if I do this thing, I'll get the print method of that particular class. And using this we are going to pass this parameter invoice inside this so that it can print in short, we are just going to use this invoice printer class.
And this is not having any new logic. It's just going to call the logic of my printing system. Now when I do this thing, as per this code, we are able to understand one thing that there is one class with the name invoice printer which is connected with printing system. But in this case, this particular connection between these two classes is actually something which is known as tightly coupled. Now, if you are a good developer who have at least two, three years of experience, then I hope you understood these two words, there is one word which is known as tightly coupled, which tells me that two different objects are going to depend on each other. And the other one is something which is known as loosely coupled, which is telling me that two objects are going to be dependent on each other, but in such a way that if you change one, it's not going to affect the other one.
In our case, right now, these two classes, invoice printer and printing system, both are tightly coupled because this class is having a constructor, which is having a parameter of type printing system. It means every time when I'm going to instantiate invoice printer, I need to use printing system with that. And if I change something in printing system, then again it's going to get affected with that. If I won't To make sure that my dependency inversion principle works with this code, I need to make sure that the connection between these classes should be loosely coupled. And that's what your dependency inversion principle is trying to tell you. Now, the question is how can I make this thing loosely coupled?
The answer is very simple. We know that printing system is a class which is implementing I invoice printer same a printing system to is also a class which is implementing I investment. This I invoice printer is the interface which is associated with this then for this printing system class, then in spite of this printing system class, I am going to use a private variable of type I invoice printer. And the moment I do this thing, you can see that my invoice printer class is taking a parameter of type I invoice printer, which is internally going to be printing system only. But it can be another implementation of I investment also. In short, the moment I do this thing, this class is not connected with any other class.
Instance is connected with just an interface. As we know interface is an abstraction. So this is not connected with the concrete implementation. This is connected with the abstraction. And that's why this is going to be loosely coupled. Architecture wise, my invoice printer class is connected with the interface which is I investment.
And if I'm using this I invoice print in any of the class like printing system, or printing system client to wherever I'm going to implement the interface. And I have a logic print, I can use that particular logic print method inside my print. So it's something like this that we are not connecting with the concrete implementation we are connecting ourselves with an abstraction. And that's where our principle number five is that is fine that your class object should not get tightly coupled it should connect with the other objects using a loosely coupled way. So we are connected with a loosely coupled way and actually instance of the class, either printing system or printing system to the actual instance of the class will get injected into this particular invoice printer at runtime. Now how this is going to get injected, that is something which I'm keeping on hold right now, in future videos.
In the same course, you can understand how dependency injection is going to work and how we are going to utilize that thing. But right now, I'm keeping this thing on hold. Because right now, the goal is to understand all five solid principles. And that's what we understood right now, before we wind up this, I just want you to understand that there are five principles and that's what we have seen in this one sample. F stands for single responsibility principle. And more than this line, I want you to understand this one liner which is we are going to understand that class is going to concern about single focus purpose.
Then we have open close principle, which is telling me that our core should be open for action. session but closed for modification, then we have liskov substitution principle. And in that we are going to take care of inheritance. And the parent cannot replace the child object seamlessly. That's what we understood. The fourth one is interface segregation principle, which is telling us that any interface should not force any methods to the class.
And to do that thing, we are going to keep only one method inside the interface. And then we have a last And the final one. And I can say the most important one, which is dependency inversion principle, which is telling me that objects should be loosely coupled whenever we have a relationship between two classes. And the injection of those objects should happen at runtime. Now how the injection will happen that we are going to see in the separate topic, which is dependency injection, and I'm going to show you that thing with code samples again, including MVC and dependency injection and all. So we'll see this thing in future videos.
Up to this point. I hope you're clear with solid plan. Now it's time to move on in C sharp with some more advanced topics. And that's why we are going to focus on abstract classes and interface in depth. Once we understand interfaces and abstract classes in depth, then I'm going to teach you some of the very cool and interesting and useful design patterns of C sharp. See you soon guys.
Thank you