I am struggling to understand the benefits of using a dependency injection framework, in my case CDI in a Jakarta EE context.
I think I see the point of the standard use case for dependency injection - it is often benefitial to "factor out" the concrete instantiation of an instance variable, so that
public class Car {
private Tyre tyre;
public Car() {
tyre = new Tyre();
}
}
becomes
public class Car {
private Tyre tyre;
public Car(Tyre tyre) {
this.tyre = tyre;
}
}
which has the benefit that now we can insert whatever tyre we like, which is handy for unit tests, for example, as Tyre might be difficult to instantiate.
Now where I am struggling, and I think where many tutorials and questions are a bit thin, is, how you can connect this with a dependency injection framework. Of course, my example would now read (when using CDI)
public class Car {
private Tyre tyre;
@Inject
public Car(Tyre tyre) {
this.tyre = tyre;
}
}
but I don't see why I have gained anything at this stage. I am aware that you could have more than one implementation of the Tyre interface, but then you would have to put another annotation on top of the injection to tell the framework which tyre is inserted... how is this any better than just putting the concrete implementation into the signature?
After summing up my current knowledge and thoughts, my question is basically how a baby example of the following progression could look like:
- Code without dependency injection and with some problems
- Same code with dependency injection where some, but not all problems are solved
- Same code with a dependency injection framework (preferrably CDI) where all problems are solved.