Super simple Dependency Injection in Swift

Chandan Karmakar
2 min readMar 1, 2024

--

It sounds fancy, but what exactly does it mean? Don’t worry; it’s not as complicated as it sounds. In this beginner’s guide, we’ll break down the concept of dependency injection in a simple and understandable way.

Imagine you’re baking a cake. You need ingredients like flour, eggs, and sugar. Now, let’s say you have a friend who loves baking and always has these ingredients ready. Instead of going to the store every time you need something, you can simply ask your friend for the ingredients you need. This is somewhat similar to how dependency injection works in software development.

Similarly let assume we have a simple dependency graph.

ViewModel depends on ApiRepo, which depends on DBRepo.

Now the idea is ViewModel doesn’t create its dependency ApiRepo directly, it asks injector for it.

So this is our target:

class ViewModel {
lazy var repo: ApiRepo = injector.inject()

func doLogin(email: String, pass: String) {
repo.login(email: email, pass: pass)
}
}

let viewm = ViewModel()
viewm.doLogin(email: "apple@mail.com", pass: "swift")

Swift has all the features that can help us write our own DI logic easily. In this tutorial we will use lazy properties instead of constructors.

ApiRepo implementation:

protocol ApiRepo {
func login(email: String, pass: String)
}

class ApiRepoService: ApiRepo {
lazy var db: DBRepo = injector.inject()

func login(email: String, pass: String) {
print("login api call")
db.getUser(email: email, pass: pass)
}
}

DBRepo implementation:

protocol DBRepo {
func getUser(email: String, pass: String)
}

class DBRepoService: DBRepo {
func getUser(email: String, pass: String) {
print("getUser db call")
}
}

Now comes Injector

protocol Injector {
func inject() -> ApiRepo
func inject() -> DBRepo
}

class MainInjector: Injector {
func inject() -> ApiRepo {
ApiRepoService()
}
func inject() -> DBRepo {
DBRepoService()
}
}

let injector: Injector = MainInjector()
// let injector: Injector = isPreview ? MockInjector() : MainInjector()

Here we are returning actual implementation of DBRepo and ApiRepo .

injector used as a shared instance.

And thats it, super simple version of DI, you can use it in your projects.

Hope you liked it.

Like and Comment 👨🏻‍💻.

--

--