Dependency Injection in Go

Daniel

September 4, 2020

Without frameworks

Dependency injection is passing a dependency to another object or structure. We do this as it allows the creation of dependencies outside the dependant object. This is useful as we can decouple dependency creation from the object being created. Lets look at an example of dependency injection in Go:

In this example we have a structure called "PersonResource", this depends on a "DataStore" type. We are passing in the DataStore upon creation of our "PersonResource". This allows any datastore we want to be used inside our PersonResource as long as it implements DataStore. An example use-case is if we want to swap out an SQL datastore for a MongoDB datastore, we wont have to change any logic in the PersonResource.

This is how it would look to create a person resource in our main function:

Google wire


The no framework approach is quite a verbose way of injecting dependencies. The main function can get very long as you can potentially have a lot of dependencies to create for a structure. Google wire is a framework which will generate the dependencies at compile time. This is meant to simulate what a developer would likely write while creating dependencies. Lets change our main package a little:

Lets build an example:

In this example we have made "PersonResource" now depend on a logger as well as the datastore. For the logger and datastore, we have added a new function that describes how these are created. In our main method, we no longer have any logic that creates the datastore or logger, instead we have a new function call "InitializePersonResource". This lives in a new file called wire.go, lets look at the contents:

All we are doing in this file is giving wire the providers needed to create a PersonResource. If we run wire it generates a file for us:

This file looks very similar to how we created the dependencies without a framework. In this simple example, it doesn't look very impressive, but if we add more dependencies to datastore and make those also have dependencies, Google wire saves us a lot of time in injecting these dependencies.

Conclusion

There are a few different approaches to dependency injection in Go. For most cases, I don't think a framework is needed, especially in micro-services or serverless architecture. However, if you are building large applications with big dependency trees, a framework like google wire could cut down on development time without adding a performance overhead as the files are generated at compile time.

Daniel

Daniel

I am a Software Engineer working as part of the nerd.vision team, mainly working on the backend systems and agents. When I'm not squashing bugs, I enjoy travelling, gaming and experiencing new foods and cultures.