5 ms·
DI is a decoupling technique. You might only have two interfaces to begin with, but the rough idea is that writing to interfaces and using IoC allows you to mak
by jolux 6y ago
DI is a decoupling technique. You might only have two interfaces to begin with, but the rough idea is that writing to interfaces and using IoC allows you to make many changes by adding code without having to change old code.
- sagichmal 6y agoSure, but you don't need a framework or DSL for this in Go.
- virmundi 6y agoI don't need them in Java or Typescript. The benefit is that I don't have to write these boring, but necessary pieces. As applications grow larger, especially with Go's desire to have an interface with only one method/function, DI requires a lot of boilerplate. If there was a DI for go that used generate, then I would have compile time checking of dependencies. This would satisfy the community's sense of purity while satisfying my sense of annoyance at having to write this same process for every project.
- skjfdoslifjeifj 6y ago> The benefit is that I don't have to write these boring, but necessary pieces. The "boring, but necessary pieces" are usually just a call to a constructor. In my opinion it's almost never worth using a DI system that obfuscates dependency resolution and usually can't be checked at compile time just to avoid that.
- throwaway894345 6y agoAgreed. It seems silly to call "invoking constructors" "boring" but doing all of the same work in XML is somehow more interesting? It seems like you're just adding in a layer of indirection that does nothing besides exchange Go/Java/etc for XML/Groovy/etc at the expense that one must be familiar with the DI framework to understand how the DI files are loaded, linked together, and mapped to your application code.
- permille42 6y agoThe main benefit of constructing objects and tying them together via DI is to allow polymorphic handling of responsibilities. It is more complex than simply "I just make an interface and make everyone agree on that interfere". Everyone agreeing on the interface to use is very unlikely. The underlying data in different implementations will be different. This is something Golang fails terribly at because it doesn't have polymorphism. This is, I believe, why there are so few DI systems for Golang, and most of them are of the sort you are referring to as silly. The way Golang works, and the reccomended patterns for Golang are somewhat anti-DI.
- throwaway894345 6y ago> The main benefit of constructing objects and tying them together via DI is to allow polymorphic handling of responsibilities. This is already provided by interfaces, as previously discussed. To be clear, dependency injection makes sense; however, dependency injection frameworks don’t make sense to me. > The underlying data in different implementations will be different. This is something Golang fails terribly at because it doesn't have polymorphism. Go definitely has always had polymorphism; that’s the whole point of interfaces. > The way Golang works, and the reccomended patterns for Golang are somewhat anti-DI. DI (assemble your object graph in main() instead of distributing it across dozens of constructors a la OOP) is idiomatic Go; DI frameworks are not.
- permille42 6y agoInterfaces don't allow polymorphism, because they don't allow you to change the underlying data. The main problem is that you can't ( or at least aren't supposed to ) use any pointers and especially not pointers that point to different data types in different situations. This sort of behavior is core to polymorphism. It can be done in three ways in Golang ( and probably more too... ): 1. Use serialized messages in channels to do all messages to objects ( disgusting imo... ) It would though at least let one emulate the behavior of message passing / routing languages ( pursuant to original visions of smalltalk etc ) 2. Use "unsafe pointers" and just do everything the pay you would in C, deliberately going against the way Golang authors want you to do things. 3. Use reflection and messy if/else in combination with code-generation at compile time. ( this is what a bunch of Golang DI systems do :( ) I don't think you understand polymorphism very well. I don't give a shit what people are calling DI frameworks these days. I also don't much care for things that simply instantiate a bunch of objects and tie them together. That is only a very elementary variety of metaprogramming. Essentially, what I am claiming is the Golang is a bad language for metaprogramming, and that in other languages the DI systems they have have become a type of metaprogramming that I think is respectable.
- sagichmal 6y ago> The benefit is that I don't have to write these boring, but necessary pieces The component graph of your application isn't boring, it's the most important part of the thing, and the starting point for anyone trying to build a mental model of the thing. It should be front and center, never hidden away behind generated code.
- jolux 6y agoYou don't need it, strictly speaking, in any language. But as applications scale, often an IoC container makes managing lots of dependencies easier.
- jamra 6y agoIn Go, you can just use an interface which would make things mockable for testing.
- ptr 6y agoBut you still need to send around the object that implements the interface, right? That’s “DI”.
- jamra 6y agoI don't think you need to do that. Assuming a web application... You can instantiate the object in your main func and then attach it to the server struct so that it is available in every request. When mocking, you can create a mock server that instantiates mock items that implement the interface. If you need something that is contextual, you attach it to the context. In that case, you can still use mock objects, however, you would have to use a different middleware that handles the mock context objects instead of the normal middleware.