DI at LinkedIn was used for development, for unit test isolation, and to reduce tight coupling.
One big problem with a giant "Application" class is that it means all of the dependencies are laid out there, and their dependencies, and their dependencies, all named and instantiated. But some dependencies are in libraries, and basic detail encapsulation means ... a factory.
Offspring wasn't much of a framework, more of a set of conventions and utilities for building that stuff in plain Java code (with key annotations). In particular, I think the Offspring setup wasn't opinionated about the framework of the rest of the application, although other parts of LinkedIn were (and presumably still are).
> One big problem with a giant "Application" class is that it means all of the dependencies are laid out there, and their dependencies, and their dependencies, all named and instantiated. But some dependencies are in libraries, and basic detail encapsulation means ... a factory.
Indeed they are - and I strongly believe that is a good thing. Because at which other place are all your dependencies laid out and instantiated? In your deployed application code at runtime.
So to understand your application in its entirety (and not just individual components), knowing the whole object graph is essential. And the easiest way to know it is if it's already written down somewhere.
This doesn't have to keep you from enforcing loose coupling and encapsulation, at least for certain definitions of those:
If you want to keep the components encapsulated - i.e. ensure that FooService works with any implementation of BarService - you can still do that: Just ensure the individual components only refer to each other through interfaces and forbid direct dependencies between them. Then in the end, the application class should be the only location in the entire codebase where multiple concrete components interact in the same class (excluding tests).
You can even enforce this by putting each components in a separate artefact and only allowing dependencies to an "API" artefact that is distinct from the implementation.
However, if you understand loose coupling such that no part of the application should know about the other, and the entire application assembles its component through some magical algorithm, I'd call into question why this is even a desirable property: You still have an object graph, you just go out of your way to hide it. And it's still very important that the object graph must be assembled in some very specific way, which is why the algorithm must be coaxed into doing the right thing with qualifyer annotations or magic priority numbers.
One big problem with a giant "Application" class is that it means all of the dependencies are laid out there, and their dependencies, and their dependencies, all named and instantiated. But some dependencies are in libraries, and basic detail encapsulation means ... a factory.
Offspring wasn't much of a framework, more of a set of conventions and utilities for building that stuff in plain Java code (with key annotations). In particular, I think the Offspring setup wasn't opinionated about the framework of the rest of the application, although other parts of LinkedIn were (and presumably still are).