Okay, so now that we have seen the other two types of dependency injection, let's look at the third
type which is interface injection.
So it involves providing dependencies through an interface that the class implements.
So the interface itself defines the methods to set the dependencies.
All right.
So let's go ahead and create a public interface that I'm going to call I Tool user okay.
So pretty cool name.
You see here the I is a capital letter.
The second letter is also capital.
So we're going to say that whenever you want to use a tool user like the builder you need to set the
hammer.
So I'm going to say give me a hammer and you need to set the saw.
And I'm going to say give me a saw.
So now the hammer still uses stuff.
The saw is also just using but the builder, that's where the change comes in.
The builder is now an I tool user, so he is now a tool user, which means that he needs to set the
hammer, and he also needs to set the saw before he can build the house.
Or at least his methods need to exist.
So we can go back to those being private fields.
So private hammer underscore hammer.
And let's add an underscore because it's private and private saw underscore saw.
Now obviously when we are using the hammer we need to say hammer use.
And when we're using the saw we need to say underscore saw dot use.
So now we still need to implement those two methods where we set the hammer and we set the saw.
So let's hover over and give us the potential fixes.
And let's say implement the interface.
And what it does is it just creates those two methods for us.
So said hammer, where we need a hammer and what we're going to do is we're going to take that hammer
and store it inside of the underscore hammer.
So what we're just saying is set the hammer that you give to me to be used as the hammer of that builder.
So the builder now gets a hammer whenever said hammer is set.
And then we do the same thing with the saw.
So just give me the saw whenever set saw is used.
So now instead of using setters we are using interfaces.
Also you could call it setters, but we're using it with a more complex architecture.
This allows us to now create more tool users.
So it would not just be the builder who can use these tools, but it could also be somebody else, like
we have the builder and maybe the house builder or whatever.
But then we also have a mechanic, okay.
And the mechanic is not a builder, but he could maybe still also be using a saw and a hammer.
And in that case we still need to provide them those so we can use set saw to set the saw.
And we can use builder set hammer to set the hammer.
So here dot set hammer and pass on the hammer.
And which saw and hammer are we passing.
Let me actually maintain the order in which we had it before.
So we are passing on the hammer that we created here the dependency.
And the same for the saw.
So we're passing those two to set hammer and set saw.
And now we can use those.
And we see hammering nails, sawing wood house build.
So you see there are multiple different ways as to how to get dependency injection running okay.
So now let's try and understand this a little better.
So interface injection in this case the builder class implements the I tool user interface which defines
methods to set their dependencies.
The advantage of this is that it gives us flexibility.
So the dependencies are injected through interface methods, allowing the class to receive its dependencies
from an external source.
Now let's compare the three examples that we had.
So we had the different injections right.
So let's compare the injection methods.
We have the constructor injection.
The pros are it endures.
All dependencies are provided at object creation time, which is pretty cool.
But there are cons to it as well.
Dependencies cannot be changed after object creation.
Then you have setter injection.
The pros is that it allows changing dependencies after object creation.
The cons are.
Dependencies might not be set at object creation time, leading to potential null reference exceptions
as we have seen.
Right?
We started running it and we saw it crashed because we didn't set the different dependencies that were
required.
Then interface injection that we just finished.
The pros are it provides a clear contract for.
For injecting dependencies through interfaces.
So all of the advantages of interfaces are in here.
But the cons are it requires additional interfaces to be fined for setting dependencies.
So the conclusion using the builder example, we've demonstrated three methods of dependency injection.
The constructor injection where dependencies are provided via the constructor setter injection where
dependencies are set through public properties or methods, and interface injection where dependencies
are injected through methods defined in an interface.
Each method has its advantages and trade offs and understanding.
These can help you choose the best approach to your specific use case.
By leveraging dependency injection, you can create more modular, flexible, and testable code.