What Is Dependency Injection?
Tags: swift, ios, tutorial
Published: 2022-02-16 22:33:39

Dependency injection (DI for short) at its core is a very simple technique, but using it will enable other advanced patterns and principles that will help you develop clean and loosely-coupled applications.

## DI Definitions
Let’s explore some popular definitions of DI.

> dependency injection is a technique in which an object receives other objects that it depends on, called dependencies.  [Wikipedia](https://en.wikipedia.org/wiki/Dependency_injection) 

In StackOverflow, the popular Q&A website for developers, John Munsch gave an excellent explanation of DI in response to the question “How to explain dependency injection to a 5-year-old?”

> When you go and get things out of the refrigerator for yourself, you can cause problems. You might leave the door open, you might get something Mommy or Daddy doesn’t want you to have. You might even be looking for something we don’t even have or which has expired.
> What you should be doing is stating a need, “I need something to drink with lunch,” and then we will make sure you have something when you sit down to eat.  [stackoverflow](https://stackoverflow.com/questions/1638919/how-to-explain-dependency-injection-to-a-5-year-old) 

Another very compact definition of DI given by James Shore:

> Dependency injection means giving an object its instance variables. [jamesshore.com](https://www.jamesshore.com/v2/blog/2006/dependency-injection-demystified) 

A final definition I will include here is one from the book *Dependency Injection Principles, Practices, and Patterns by Steven van Deursen and Mark Seemann*. It’s a bit advanced, which states the whole goal of DI:

> Dependency Injection is a set of software design principles and patterns that enables you to develop loosely coupled code.

I will write in this blog about many of these principles and patterns. So be around! For now, let’s try to use DI in Swift.

## DI in Swift
Here is a basic DI example in Swift:

```swift
class Profile {
    private let user: User
    
    init(user: User) {
        self.user = user
    }
}
```

The *Profile* class doesn’t create a *user*; it **states** that it needs a *user* in order to instantiate it. Clients of the *Profile* class will need to supply the *user* dependency.

Swift is a general-purpose and multi-paradigm programming language. You can write Swift code in an imperative style (object-oriented programming or procedural programming) or in a declarative style (functional programming).

In Swift, we have *classes*, *structs*, *enums*, *methods*, and *functions*. All of these types can receive dependencies which are other *classes*, *structs*, *enums* or *functions*.

Here is an example of a function that receives a dependency:

```swift
func calculate(bill: Bill) -> Int {
    var result = 0
    bill.items.forEach { result += $0.cost }
    return result
}
```

Another example where a function receives another function as a dependency:

```swift
func print(bill: Bill, billCalculator: (Bill) -> Int) {
    bill.items.forEach { print(“\($0.name): \($0.cost)”)}
    let total = billCalculator(bill)
    print(“Total: \(total)”)
}
```

## Conclusion
We only scratch the surface of DI. There are many benefits that DI enables, such as late binding, dependency inversion, extensibility, and testability. We will explore them in the next post.