←back to thread

257 points pmig | 5 comments | | HN request time: 2.431s | source
Show context
bryancoxwell ◴[] No.43096481[source]
> But there are obviously work around solutions in the Go ecosystem. It uses the Context ctx, which we pass around functions in order to juggle data around in the application.

Man. This works. The context API allows/enables it. But I’d really recommend against passing data to functions via context. The biggest selling point of Go to me is that I can usually just look at anyone’s code and know what it’s doing, but this breaks down when data is hidden inside a context. Dependency injection is entirely possible without using the context package at all, interfaces are great for it.

replies(8): >>43096604 #>>43096796 #>>43096956 #>>43097757 #>>43098179 #>>43098205 #>>43099616 #>>43099625 #
roncesvalles ◴[] No.43099616[source]
IoC DI in Go is a massive antipattern and absolutely should not be done. Do NOT write Java/.NET style controllers in Go i.e. initializing an instance of a "controller" type with some instances of a "dependency" such as a store.

Just use the dependent package directly. Initialize the package once using init() or Init(). Rely on the built-in package dependency resolver system in Go, which will catch cyclic dependencies, call init() in topo order, and other such things.

Test using monkey-patching. Stop using interfaces just to be able to swap a real thing with a mock implementation. These are all symptoms of writing Java in Go.

replies(6): >>43099670 #>>43099699 #>>43099767 #>>43099845 #>>43101885 #>>43194806 #
1. someothherguyy ◴[] No.43099699[source]
So, write python in go instead, gotcha.
replies(1): >>43099736 #
2. roncesvalles ◴[] No.43099736[source]
The idiomatic way to write Go is as naively as possible after you fully understand how it works. Otherwise it'll just feel like Java with shitty ergonomics.

If you're ever writing Go and wish you had real classes instead of this deconstructed "mess" with struct types, methods, and interfaces, you're writing Go totally wrong.

replies(2): >>43100727 #>>43101395 #
3. gf000 ◴[] No.43100727[source]
Sounds like a no true Scotsman fallacy.
4. unscaled ◴[] No.43101395[source]
That is certainly one way to write Go, but I wouldn't call it "idiomatic" when evil the Google Best Practices guide recommends against it[1][2]. I'll wager you'll probably find it in most other Go style guides. This is how the Go standard library itself works. While you can use http.Get() if you want to use the default HTTP client for simple apps, the library provides you the http.Client struct, where you can also override the Transport (RoundTripper interface) and Jar (CookieJar interfaces). The transport interface lets you further override the Dialer and Proxy function.

[1] https://google.github.io/styleguide/go/best-practices#global... [2] https://google.github.io/styleguide/go/best-practices#provid...

replies(1): >>43101709 #
5. roncesvalles ◴[] No.43101709{3}[source]
The example they've chosen is somewhat contrived in that the dependency is maintaining a collection of plugins. In such a case it makes sense to go with their approach. I'm not actually arguing against having multiple instances of some package's functionality; indeed such instances may be created and stored per controller. I'm more so arguing against IoC style Dependency Injection, i.e. central instantiation of the controller and its dependencies. My point is just, as far as possible, it's better to rely on init() and package import relationships. You can simply call dep.New() in any number of inits.