When changing to a new company you are often faced with new technologies, a new way of working. This was the case for me as well as all of a sudden I was introduced to Dependency Injection. Even more, they have build their own framework for it on top of Guice. While the details of it all still are foggy to me, I have used it and will share my experiences here with you.
There are probably a couple of reasons for using Dependency Injection, but the main reason why they used it was because they used OSGi before, which has a similar mechanism. I found this a bit weird to hear, as I have worked with OSGi before, but was never confronted with this, but then again I never was too familiar with OSGi either. Or maybe it was because we were building an application on top of Eclipse and the actual injection happened with Eclipse and not with our own code. Another reason for it was to avoid having singleton objects which often is a pain to do some decent unit testing.
I am a deep believer of having testable code, and actually testing your code by unit tests and other kind of tests. I’m also not really a big fan of the singleton pattern and I try to avoid it whenever I can and I favor static methods over the singleton every time. Sounds like I really will enjoy Dependency Injection then, as it makes my life a lot easier and solves all this nastiness. Well, not really… maybe it’s because I haven’t used it before, but I am not really fond of this Dependency Injection.
First of all the complete disruption of traceability, while with a normal constructor or method calls, you can easily check who calls it, and trace back to the origin of everything, leaving you with a nice flow of how everything is coupled together. With Dependency Injection this is completely broken in both ways. As the constructors are nowhere called, and the objects are automatically instantiated and injected where needed you miss the overview of where the objects are used. In the other direction you can just inject any object you want and not have a clue what’s really in the object. This is not a concern if the object does not contain any fields and just a set of methods, if it does contain fields , will you get a new instance or a shared one?
Another very personal reason for me, is that I just don’t see the point. Do we such complicated mechanisms to avoid calling a constructor? What did we gain by doing this? Are things made easier? Is it only for testability? I can assure you that the framework I have to use now does not make things easier, as you have to ‘register’ the objects in a separate file for the framework to pick it up. Keeping this file in sync with your code is all manual work without any assistance making it a lot harder and more cumbersome. For the testability part, there are many other ways to keep your code testable. While I do believe that good code in itself is most of the time very testable, there are powerful frameworks that can help you with it in those cases that it’s not the case. I favor having a cumbersome framework for tests over a cumbersome framework for the code, simply because making your code harder to understand and maintain for easier tests is clearly the wrong approach.
My final objection might be very related to the framework and not so much to Dependency Injection. The framework I have to use is designed for services without any fields, which is good. But it forces us to have an interface or abstract class and an implementation, while many of you will have no objections against it, and other may even prefer it this way, I do not like making an interface for my service because there will be no other service with the same interface. Moreover the framework forbids it that multiple registered implementations implement the same methods. Basically nullifying the point of having an abstract class or interface, and all you end up with is a larger set of files to go through until you find what you are actually looking for.