3 ms·
> First off you aren't using interfaces, which makes it unclear how you're writing test versions of your classes Use interfaces if you want, there are differen
by vbezhenar 5y ago
> First off you aren't using interfaces, which makes it unclear how you're writing test versions of your classes
Use interfaces if you want, there are different approaches to testing. Some classes are fine to inject as they are. Some classes are fine to mock with libraries like Mockito. And sometimes interfaces makes sense.
> For example if I have multiple setService (e.g. serviceA, serviceB, and serviceC) and I want to call .afterPropertiesSet(), how do I know which it depends on externally?
I'm not sure I follow you. You just wrote that class, surely you know what dependencies you need.
> There's a very, very, good reason why all DI frameworks have you use interfaces and the class's constructor to inject.
You're wrong here. I don't know a single DI framework that forces you to use interfaces and constructors. Setter injection or field injection is supported everywhere, at least in Java world.
> By decoupling that assumption from those calls, you've created a development hell (i.e. this is an unmaintainable mess).
I used that approach. It works good and it scales without issues with quite complex dependency chains. One issue is a little bit of mundane work, but it's not a lot and simplicity worth it.
> There're two good ways to do DI:
> - During class construction. They then always exist in the class's scope.
Constructor injection is terrible approach to use without DI framework. You'll need to move your initialization code around almost every time your dependencies change. You inevitably will invent yet another DI framework, buggy and incomplete and at this point you lost. Also it does not allow for circular dependencies, which sometimes are necessary. Another point is that Java does not have named parameters and long constructor calls are hard to read (recent Idea improves that a little bit with inlay hints, though).
> - Every method call individually takes in all explicit dependencies (e.g. GetMagic(iDatabase database, iDateTime dateTime, ...)).
That's not a dependency injection, as it requires to pass dependencies through every call chain. If you suddenly need some service deep inside your chain call, you have to change all functions which lead to that call. It might be a suitable approach for some 1000-LoC one-file program, but it does not scale.