Given this code:
package main
import (
"fmt"
)
type datstr string
type Guy interface {
SomeDumbGuy() string
}
func (d *datstr) SomeDumbGuy() string {
return "some guy"
}
func someConsumer(g Guy) {
fmt.Println("Hello, " + g.SomeDumbGuy())
}
func main() {
var d datstr
someConsumer(&d)
}
Is the wiring of components together that's done in main the right way to wire a dependency together? It seems like I'm over using this a bit in my code. Is there a common pattern better than this, or am I overthinking it?
Google's Wire looks promising. There're some articles about it:
Compile-time Dependency Injection With Go Cloud's Wire
Go Dependency Injection with Wire
You should also try Dargo, which is new but has some features that the facebook one doesn't have. The code is here.
Here is an example:
In this example a service called SimpleService will inject a logger. The logger itself is a dargo service that is bound with a creation method. That creation method looks like this:
The binding of SimpleService will provide the struct that should be used to implement the interface. The struct has a field annotated with inject followed by the name of the service to inject. This is the interface and the struct used to implement it:
Both the logger service and the SimpleService are bound into the ServiceLocator. This is normally done near the start of your program:
The returned locator can be used to lookup the SimpleService service. The SimpleService is bound into the Singleton scope (the default scope), which means that it will only be created the first time it is looked up or injected, and never again. The LoggerService, on the other hand is in the PerLookup scope, which means that every time it is injected or looked up a new one will be created.
This is the code that uses the looked up service:
Any depth of injection is supported (ServiceA can depend on ServiceB which depends on ServiceC and so on). A service can also depend on as many services as it would like (ServiceA can depend on service D, E and F etc). Howerver, services cannot have circular dependencies.
Best practice is not to use a DI library.
Go is meant to be a simple language which is easy to follow - without you having to look up how things are working under the hood.
A library/framework will abstract that away from you...
What you're doing is pretty much correct.
Source: https://www.youtube.com/watch?v=PTE4VJIdHPg&list=WL&index=87
This same explanation was also provided in the blog of Peter Bourgon: https://peter.bourgon.org/go-for-industrial-programming/
Lastly Danny explain how he user DI in Go after 2 years working in Industrial Programming: https://medium.com/@madannyaguswahyudi/how-i-structure-go-code-after-2-years-working-in-industrial-programming-17ed5ef83e1e
Yes, the facebookgo inject library allows you to take your injected members and will wire up the graph for you.
Code: https://github.com/facebookgo/inject
Documentation: https://godoc.org/github.com/facebookgo/inject
Here's a code example from the documentation:
If you're still interested in finding a DI library for Go that uses very minimal reflection I made one called axon. It's based on Google's Guice so if you're coming from the Java world (like myself) it should lend itself well to how you expect it to work.
I've used it in web servers and it hasn't had any problems and was fast enough to not have any impact on being used within CLIs.
Uber's Dig is pretty awesome. Here's a great blog post about it: Dependency Injection in Go