Dependency Injection

Learn about dependency injection, its benefits, and how it can be used in Go.

Dependency injection (DI) is a software design pattern that aims to separate the building of a dependency from its usage. It’s based on the concept that we don’t have to instantiate a dependency in the same place where we’re going to use it. The burden of constructing is exported to another component of our software, which acts as a builder. If we initialize the dependency within our function, we introduce a rigidity that can prevent us from writing flexible and testable code

Press + to interact
func sendEmail() {
// dependency initialization
emailClient := email.NewClient()
// dependency usage
emailClient.SendEmail()
}
// dependency is provided to the function
func sendEmail(emailSender MailSender) {
// dependency usage
emailSender.SendEmail()
}

The previous code snippet shows us how to achieve dependency injection in our code. As a rule of thumb, if we create an instance of a struct within the same component that will use it (maybe with the := operator or the new keyword), we’re not using dependency injection. If we rely on it, it’s easier to build loosely-coupled code that will result in more reusable, flexible, and testable code.

In this lesson, we’ll explore DI features by using an example application to learn its benefit in software development.

Build an online course platform

The application we’ll ...