13 ms·
I haven't really touched Java in a while but I don't get why you'd want a lightweight DI container. You can just build your object graph and pass dependencies
by hocuspocus 5y ago
I haven't really touched Java in a while but I don't get why you'd want a lightweight DI container.
You can just build your object graph and pass dependencies manually if you want a lightweight approach, no? That's just the way people do it in most languages.
- throwaway894345 5y agoAgreed. Stuff like this feels like magic for magic’s sake, and as someone who has had to operate services that use these DI frameworks, they are a big pain.
- throwaway1492 5y agoWhat does “operate” mean in this context? I’m generally curious why one should consider this comment to be anything other than low effort flame bait?
- throwaway894345 5y agoOperate means “run the service”. If you need to configure things which aren’t well documented, it’s nice to be able to look at the code, but the DI frameworks obscure the code path. This is pretty straightforward; no idea why this would seem like flame bait—I didn’t even realize this was something people held deep emotional attachments to.
- kaba0 5y agoHow about learning about the tools you use beforehand? You don’t sit into a car without any knowledge about it and blame it that it is magical.
- deleted 5y ago[deleted]
- throwaway894345 5y agoI read all of the documentation for the service that I operate--per my other comment (https://news.ycombinator.com/item?id=29973282 https://news.ycombinator.com/item?id=29973282), often times things aren't well-documented and it's crucial to be able to look at the source code to figure out what something does (e.g., how is a configuration parameter used? what are its valid permutations?); however, when the source code is obscured by gratuitous complexity then it imposes a high cost on the user and in the case of DI frameworks, that gratuitous complexity comes with no discernible benefit (a car offers me something of value to justify its learning curve). Personally I'm of the opinion that a person shouldn't have to be a seasoned Java developer to use so many tools that are implemented in Java (or any other language, for that matter).
- waynesonfire 5y agohere is the talk, good stuff, Dead-Simple Dependency Injection https://www.youtube.com/watch?v=ZasXwtTRkio https://www.youtube.com/watch?v=ZasXwtTRkio
- eximius 5y agoReplacing DI with Free Monads is not what I'd call simple. It's not even possible in a type safe way in most(?) languages.
- WatchDog 5y agoI think there are a lot of Java developers, that have just never worked without a DI framework, and just don't have a grasp on just how simple it can be to write code without one.
- yashap 5y agoThat REALLY depends on the size of your codebase. When it’s small, no need for a DI framework. But when it grows large, it becomes quite a pain, and a DI framework is nice, eliminates a bunch of boilerplate with every code change.
- eximius 5y agoAs someone who hated Java, used it for a few years, and now occasionally misses it... I only miss DI. I miss being able to say "this system depends on these external things" and having a consistent, convenient way of sharing/swapping/testing those components and dependencies. The solution in other languages? Unstructured globals, deep argument passing, or monkey patching with mocks?! Yea, I can write simpler code without DI... By ignoring a bunch of stuff.
- WatchDog 5y agoYou can do DI without a framework. If you write classes with final fields, with a constrcutor that takes the class' dependencies,and don't use static fields to hold mutable data. You are doing DI. Just call `new` yourself, instead of having the framework do it for you.
- jcelerier 5y agoBut how do you handle configuration then ? At some point you want a user-facing UI where the available features (which are generally classes) are listed and the user can choose the feature, say which log backend is enabled, without having to change code - that's the whole point of it. (And the most tedious code to write by hand - a complete waste of time)
- 5y ago
- stickfigure 5y agoSure, and eventually you end up rebuilding an [ad hoc, informally-specified, bug-ridden, slow] DI container because: * Static references become a tangled mess, and you start wanting some structure around that. * You have to answer "how does ABC component get access to DEF?" for increasingly difficult combinations of ABC and DEF. Excepting Spring, pretty much all Java DI containers are lightweight.
- throwaway1492 5y agoThis, it’s really exhausting to read this never ending wheel reinvention. Sure any one can use simpler non-spring frameworks, and other “non standard” frameworks and libraries for 1/10 or 1/100 of the functionality, and get 10-100x the bugs and much less or zero support. But we need netty! And then when you add thread pools, jdbc, logging, etc? Yep you’ve reimplemented spring. Just use spring, spend the time to learn it and reap the rewards.
- wtetzner 5y agoAs someone who dealt with a ton of Spring in the recent past, I completely disagree. First of all, thread pools are part of the standard library. Spring adds little to no value on top of it. Second, reinventing some of that stuff is absolutely worthwhile, because Spring's library design/implementation is not very good. Finally, when I had the opportunity to start a new Java project, I opted to not use Spring. I finally had a server that started up fast, took less code than a Spring project, was easily navigable in an IDE, and whose code was generally easier to follow. It was also easier to write tests for. One thing I learned is that people seem to underestimate just how thin Spring's abstractions are over stuff in the library, servlets, etc. Most of what Spring does is wrap things in a bean interface so they can be used with DI (which is something I’ve never found any value in).
- geodel 5y agoWell you are missing one of the great feature of Spring framework: Converting compile time errors in to runtime exceptions. Jokes apart you are absolutely right about non-spring based services. I did same using plain Java + embedded tomcat for some services. No cargo-cult like endless decorative packages and classes. Exactly same result as you observed. Less code, fast to start and vastly improved error management.
- lmm 5y agoPlumbing the construction of your object graph manually does not have a particularly high cost/benefit - most of your services are singletons that depend on each other, and it's already clear enough which ones depend on which others without repeating yourself. A very basic "here's a bag of classes that depend on each other, wire them all together and then let me pull out the instances by type" is often worthwhile for avoiding all that boilerplate, even if it does break the rules of the language a little. Something like Picocontainer or even Guice is pretty good IME.
- dep_b 5y agoNot using Java but generally in OO languages I ended up passing forward dependencies in grouped and themed classes like LoginDependencies, InboxDependencies etcetera. Everything under an Interface so you just mock whatever you need. Never ran into serious issues. Of course logging might be static but “true” dependencies like networking classes never are.
- EdwardDiego 5y agoI want lightweight, and compile time. But I'll take compile time only if need be. In terms of lightweight, I have never needed to use the @Alternative binding [0]. Nearly all of my needs are met by being able to define "this is a singleton, this is a dependency that you should always inject a new instance of, and this is a property." But it's surprisingly hard to find DI that limits itself like that. The DI in Micronaut and Quarkus are probably the closest to my ideal. Compile time, and only implement a subset of CDI etc. [0]: https://netbeans.apache.org/kb/docs/javaee/cdi-validate.html https://netbeans.apache.org/kb/docs/javaee/cdi-validate.html
- jillesvangurp 5y agoA good DI framework just saves you from having to spell out all the glue code; or at least minimize that. DIY dependency injection is indeed a useful skill to have with other languages. Unfortunately, it's not what a lot of people do with other languages because they simply don't know that it would help them. Particularly in the javascript world there seem to be a lot of people struggling to write good, testable code mainly because they make the rookie mistake of not separating their glue code from their business logic. Basically they have bits of code that initialize whatever and they need to put it somewhere and it ends up in the wrong place and before you know it, it becomes impossible to isolate any functionality such that you can actually test it easily without booting up the entire application. Add global variables to the mix and you have basically an untestable mess. I still use Spring (but very selectively). They've added multiple styles of doing DI over the years, which is confusing. The latest incarnation of that uses neither reflection nor annotations and is very similar to the type of code you'd write manually if you had the time to clean it up and make it nice to use. Another benefit is that it enables native compilation, which with the recent release of spring-native is now a thing people do. Spring is large and confusing but the DI part is actually pretty easy to use. If you've used Koin or Dagger on Android, it's similar to how that works.
- hocuspocus 5y agoI've used Spring DI. I understand the argument for it, when building bigger applications, though it invariably brings its own complexity too. What you say about compile-time DI to allow native images makes me feel like we've almost come full circle. I'm still not convinced you need automatic DI at all for smaller services.