I am looking for help to decide which dependency injection framework best suits our needs and whether or not this is the way to go in the first place.
I am working with a codebase of ~300k lines of code. We have an array of "main" customers, as well as an additional large customer. The latter required an individual version of our software which we then provided.
Since then a prospect to cooperate with further partners appeared. In future some of them may require individualized software versions - this may range from mere UI design up to excluding large sections of functionality.
Therefore we currently aim to modularize our codebase, preferrably using dependency injection (DI).
The codebase is written in Java, however we use JNI and implement a large chunk of the functionality in C++. This should be considered when deciding framework suitability.
Currently we mainly aim to modularize product lines, i.e. large sections of our codebase. In practice however, there will very likely be modularization of medium to small features as well.
At the moment a DI solution is favored, though this is not a requirement. Frameworks I am looking into are mainly:
- Dagger 2
- Spring DI
Besides these there are more solutions that are at least briefly considered:
- Java EE6 CDI
Aspects we are considering:
- Modularization capability
- Effort to utilize framework in large codebase
- Performance, especially w.r.t. memory usage
- Code obfuscation (Not top priority, however some suspicions arose, whether one of our customers attempted to decompile our code, therefore we will have to consider this too
So far this seems to be the favorite. The framework avoids reflection, which is desired, especially w.r.t. memory usage, as this is a resource limitation for our customers.
Debugging Dagger 2 appears easier than with Spring and Guise, due to proper traceability and their focus on human-readable class names.
Last but not least, there seems a way to obfuscate code using ProGuard. Also boilerplate is minimized.
However I am considering Dagger 2's learning curve, as some claim it can have a high degree of complexity. Also it seems
@Override is not supported by Dagger 2 which results in need for more refactoring as such classes will need to be split into modules if they are to be injected.
Also a problem is finding errors only on runtime if something goes wrong with the injection. This has potential for customers to run into runtime errors that have gone unnoticed on staging.
Like Spring DI, Guise already has a large community, something Dagger 2 may yet lack, thus finding answers to questions may be easier. A large advantage towards Spring DI is connecting classes using type information.
However, also like Spring DI, Guise uses reflection, therefore performance-wise it is not that great. For memory-related considerations this is a minus.
Dagger 2 developers claim to have put a focus on better debugging capability, they also claim that with Guise, some breakpoints may not even be understood on execution. Therefore some applications using Guise may be ill suited for debugging purposes altogether.
This appears to be the old-timer amongst the frameworks. There is a giant community behind Spring, so everything is likely to be well documented and answers should easily be found online. However the Spring community appears to be rather inactive, meaning while there are a lot of answers available online, new ones are hard to come by.
Framework uses XML, though I read that there is also the option to use annotations. Both cases are reflection, therefore again not optimal when considering RAM usage.
Functionality such as Eclipse's F3 is not available when dealing with injected dependencies. There is Spring IDE, however this is not considered an option at all.
Spring DI comes with large amounts of boilerplate code, something that is noteworthy with our codebase of 300k lines.
Mostly I would like to hear your opinion on these frameworks, whether or not you recommend one and whether your consider any of them suited for the task I described. These things interest me especially:
- Are these frameworks suited for the modularization we intend to achieve?
- Is the performance difference as noteworthy as it seems?
- Are there any important factors I should consider when deciding upon a framework that are not mentioned yet? Maybe some of you see typical hardships when dealing with DI that are apparent to you regarding our setup that are not apparent to me at the moment.
- Do Spring DI or Guise offer code obfuscation? And is ProGuard as easy to include as is claimed?
- Should other frameworks be seriously considered given the codebase as described?
In general I am greatful for any insight on this topic, since I am no expert on DI. If you see any red flags in this description, especially glaring reasons for why any of the frameworks available are absolutely not a good choice in our case, then this is valuable information.