Live data from Hacker News

Dependency injection in Go with Uber-go/fx

vincent.composieux.fr

51–60 of 96 posts

Re: Dependency injection in Go with Uber-go/fx

#51
post #19

Earlier quoted context omitted.

By using a mock?

How do you convince the when-to-fire-logic to act on a mock, if the torpedo implementation is not provided from outside it? I'm wondering if I have the terminology understood differently to other people, because to me, DI == IoC. DI Frameworks are build on top of the concept that dependencies will be injected, but doing it explicitly in your start-up code is the same thing to me.

In languages like JS/Python, you can mock imports. Actually, sometimes you can mock things defined in the same file if you set things up right.

Basically, the logic not being inlined into the function is enough to provide this behavior in certain languages.

This is not true for other languages, which is why DI frameworks tend to be more useful there.

In go specifically, I just always throw the dependencies behind an interface and shove them into a struct. Then you just create a struct of mocks for your testing.

Re: Dependency injection in Go with Uber-go/fx

#52
post #21

I'd like someone who knows more about software engineering than I do to tell me why I'd use this over some big globals-but-not-really App struct that holds all of the various dependencies of my app that I can just pass into the different parts of it so they can all access what they need. If those struct members are typed to interfaces and not types, then it's just as testable, too, because you can drop in mocks as re…

It's not terrible to have one big struct, but sometimes it can inhibit the reuse of components in more than one system. When you call a function that takes this struct as an argument, how do you know which members of the struct really need to be populated? Its dependencies aren't clearly documented. (They are over-specified. It's like a function with many unused arguments.) If a subsystem only uses some members of th…

> how do you know which members of the struct really need to be populated

Interfaces + duck typing? Your function shouldn’t ask for the struct, but rather for an interface describing what it needs.

Practically, though, I often just ask for the struct because I’m a slob.

Re: Dependency injection in Go with Uber-go/fx

#53
post #33

"Dependency Injection" should be just shorthand jargon for "pass a pointer/reference to the dependency into the constructor". Unfortunately, thanks to enterprisey-OO zealotry, it's become a terrible monstrosity of frameworks, obfuscation-by-configurable-injection, and other terrible practices. Every single application I've worked on where DI (in practice, not theory) is in use has been fragile, hard to debug, hard to…

Given a list of pairs, where one is an object and the other the arguments of the constructor, find a way to construct all of the objects. Topological sort and run. That’s all there is to dependency injection and I cannot imagine a graph so large that I would care for toposort

This leaves out lifecycle management.

Which, yes, some lifecycles are confusing. But using them well can be very beneficial

Re: Dependency injection in Go with Uber-go/fx

#54

I've never been convinced by DI frameworks. I've always enjoyed the fact that the Go ecosystem leans away from them and I would hope things stay that way. In my experience they just obfuscate what should be a straightforward, explicit process of setting up your app in main. The less magic happening there the better.

I have (and probably will) never voluntarily use a DI framework in any language. There's zero downside to manually doing it. It's explicit, incredibly easy, and you can easily trace backward to see how the program is constructed.

On the same note, I could never really get on with Aspect Oriented Programming. Coming from Java world, I got tired of seeing annotations everywhere and understanding what magic is going on. I like simple and straightforward languages.

Re: Dependency injection in Go with Uber-go/fx

#55
post #33

"Dependency Injection" should be just shorthand jargon for "pass a pointer/reference to the dependency into the constructor". Unfortunately, thanks to enterprisey-OO zealotry, it's become a terrible monstrosity of frameworks, obfuscation-by-configurable-injection, and other terrible practices. Every single application I've worked on where DI (in practice, not theory) is in use has been fragile, hard to debug, hard to…

> Every single application I've worked on where DI (in practice, not theory) is in use has been fragile, hard to debug,..

From what I have learned working at various jobs it seems to be the feature and not bug in system design. When things break it is considered a problem worthy of attention of those numerous architecture astronauts. It would have just been college project if things work without any fuss.

Re: Dependency injection in Go with Uber-go/fx

#56
post #2

I've used dependency injection heavily in Java in previous jobs, and, later, spent a few years doing Golang at another job. I never missed it. What does dependency injection give you that a simple combination of Singletons, Constructors, and Factories doesn't? I feel like the only thing you get is the ability to combine multiple independent dependency trees without having to make a sane structure. Kind of like, what…

>What does dependency injection give you that a simple combination of Singletons, Constructors, and Factories doesn't? You don't need to create a "simple combination" of Singletons, Constructors, and Factories.

Don't you? In Java I still had to create the Singleton/Constructor/Factory etc. and register it with the framework as a provider of that type.

Re: Dependency injection in Go with Uber-go/fx

#57
post #2

I've used dependency injection heavily in Java in previous jobs, and, later, spent a few years doing Golang at another job. I never missed it. What does dependency injection give you that a simple combination of Singletons, Constructors, and Factories doesn't? I feel like the only thing you get is the ability to combine multiple independent dependency trees without having to make a sane structure. Kind of like, what…

I think you are confusing dependency injecting with frameworks that facilitate it. You are probably using the former with constructors

What's the difference? Isn't the 'injection' part the part where you don't need to connect point A and point B?

Re: Dependency injection in Go with Uber-go/fx

#58
post #12
post #2

I've used dependency injection heavily in Java in previous jobs, and, later, spent a few years doing Golang at another job. I never missed it. What does dependency injection give you that a simple combination of Singletons, Constructors, and Factories doesn't? I feel like the only thing you get is the ability to combine multiple independent dependency trees without having to make a sane structure. Kind of like, what…

> What does dependency injection give you that a simple combination of Singletons, Constructors, and Factories doesn't? Easy refactoring of an interface/constructor? I've been using go for a while, and I decided to follow the advise of not using a DI for my project. Every time I refactor a constructor, it is a fun hunt to make the same changes everywhere I'm using that constructor.

That's true. However, the decoupling that occurs when refactoring one and not the other creates two different code structures, often with different levels of abstraction. I saw the same thing happening with a combination of react and redux, an it made debugging weird behaviors really, really, hard.

Re: Dependency injection in Go with Uber-go/fx

#59

I've never been convinced by DI frameworks. I've always enjoyed the fact that the Go ecosystem leans away from them and I would hope things stay that way. In my experience they just obfuscate what should be a straightforward, explicit process of setting up your app in main. The less magic happening there the better.

Not just that, but I don't understand why users would be so eager to kill type safety in their applications. If i'm understanding, these injection methods are totally type-unsafe and construction errors are deferred until runtime?

https://pkg.go.dev/go.uber.org/fx#Provide

Re: Dependency injection in Go with Uber-go/fx

#60
Maybe it's just my bad luck, but the projects I've seen from the inside where DI was used, it all turned into a dogawful blob of spaghetti code.

It was OK -- quite good, really -- in small projects... but of course pretty much any organizing principle is workable in small projects. Good organization needs to scale up.

I'm not quite ready to write it off.

For one, those large projects used a framework. Perhaps the lack of friction helped lead to thoughtless injection.

And, of course, no organization scheme can prevent the spaghetti when the project and its leadership are disorganized.

So I'm not quite ready to write it off, but I'm awfully skeptical. And it certainly doesn't seem necessary.

Post reply on HN