←back to thread

257 points pmig | 2 comments | | HN request time: 0.001s | source
Show context
evil-olive ◴[] No.43096678[source]
it's really weird to see a "Dependency Injection & Context" section as if Golang's context has anything at all to do with DI.

in particular, reading between the lines here:

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

suggests to me that they've implemented one of the Golang anti-patterns that I find most annoying - overloading the context and using it as "grab bag of pseudo-global variables"

in this anti-pattern, you have an HTTP request handler, and want to make a database query, so you need access to the database connection pool. having a global variable for the connection pool feels wrong...so what many people do instead is call context.WithValue in their server startup code to put the connection pool into the grab bag, and then in the request handler call ctx.Value to pull the connection pool out of the grab bag.

the Golang docs [0] explicitly say not to do this:

> Use context Values only for request-scoped data

the much better way, in my experience, is to make the request handler a method on a struct, and then the struct holds references to things like the connection pool. this can also be done with closures and captured variables, of course, but that tends to get unwieldy for non-trivial usage.

if you do this, then your "dependency injection" in Golang tends to look pretty much identical to how it would look in Java, if you wired everything up by hand rather than using a framework/library. and then if you want, you can use a library such as Fx [1] for automatic Dependency Injection along the lines of Spring Boot.

0: https://pkg.go.dev/context#WithValue

1: https://github.com/uber-go/fx

replies(1): >>43097121 #
paulddraper ◴[] No.43097121[source]
> as if Golang's context has anything at all to do with DI

Yes, Go's context can be used as a DI container.

replies(2): >>43097338 #>>43097730 #
1. tomcam ◴[] No.43097338[source]
I thought it was mostly used to terminate an asynchronous event?
replies(1): >>43097690 #
2. paulddraper ◴[] No.43097690[source]
Yeah it can inject a signal for that.