Live data from Hacker News

Dependency injection in Go with Uber-go/fx

vincent.composieux.fr

21–30 of 96 posts

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

#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 required.

What am I missing? This just seems like a way of obfuscating the fact that, in any modern program, we're going to need 3-20 "global variables" that aren't actually global global (but in practice are singletons in the process).

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

#22
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

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

#23
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.

JS allows you to override global objects, pretty much nothing is constant or immutable in JS. You can (more or less) replace arbitrary functions in any place, at any time.

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

#24
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.

No, you understand perfectly well!

This is the same conversation I had with the new hire I mentioned. And as the other comment here mentioned, it's JavaScript. You simply overwrite the object method with the mock at runtime of the test, then restore it after the test finishes running.

Most JS testing frameworks do this under the hood I believe, without any change in how you write your code. It's a fundamental difference in how JavaScript handles things versus something stricter like C#.

It's a dangerous footgun if you use it carelessly, of course. But a useful language feature when applied carefully.

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

#25
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…

Just come out and say it: DI is an anti-pattern. No implementation of it that I'd ever use was doable without a good config file schema, and at that point I have to ask: why not just have a declarative build system in the first place as the modern generation of Devops tools does? DI just burdens and litters code unnecessarily with awareness of build files.

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

#26
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…

100%

I've never understood the motivation for these kinds of tools. Have always come across as over engineered.

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

#27
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…

Just come out and say it: DI is an anti-pattern. No implementation of it that I'd ever use was doable without a good config file schema, and at that point I have to ask: why not just have a declarative build system in the first place as the modern generation of Devops tools does? DI just burdens and litters code unnecessarily with awareness of build files.

You, as many people here, are again mistaking dependency injection with dependency injection containers. You don't need containers for dependency injection, most codebases can just wire everything by hand without any problem.

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

#28
post #9

For a slightly different take on this problem, check out Wire ( https://github.com/google/wire ).

Having used both, I very much prefer wire's compile-time satisfaction vs fx's runtime satisfaction.

If I miss something, I'd much rather know when I try to compile instead of waiting 'til a specific code path that uses a missing dependency fails.

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

#29
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…

We use Uber/fx in the org I work.

Took me a while to buy into it, because as you said, it doesn't seem any better than hand-written code.

But after a few years I noticed fx was being adopted by more and more teams, and it reduces cross-project contribution friction, some teams started building conventions around it, and more importantly, iterating on these conventions, etc. It's become just really handy for us.

This is many many small teams (5 people per team, more than 4k devs around many offices and countries).

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

#30
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.
Post reply on HN