Discover Dependency Injection


You’re more of a video kind of person? I’ve got you covered! Here’s a video with the same content than this article 🍿


Dependency Injection can feel a bit mysterious when you’ve never used it 😶‍🌫️

But I swear it’s really easy to understand! 😌

In just a few paragraphs we’ll go over everything you need to figure out how this pattern works!

Let’s start with this ViewModel:

This ViewModel has a dependency of type Service.

And we can notice that, for now, the ViewModel is responsible for both creating and using its Service 🤨

But this is not very flexible, because it makes it difficult to change the way our ViewModel is configured 😰

That’s why it would make sense to be able to inject the dependency Service inside the ViewModel!

So let’s do it in 5 easy steps 🚀

Step 1️⃣, we create a protocol with the API of the Service:

Step 2️⃣, we hide the implementation of our Service behind that protocol:

Step 3️⃣, we implement an initializer for the ViewModel:

Step 4️⃣, we can now use this initializer to inject the Service in the ViewModel:

Step 5️⃣, if needed we can now also inject a mocked implementation of the Service:

And that’s it, we’ve successfully implemented a simple version of Dependency Injection 🥳

Here’s the code if you want to experiment with it!

protocol Servicing {
    func fetchData(_ completion: @escaping (Int) -> Void)
}

class Service: Servicing {
    func fetchData(_ completion: @escaping (Int) -> Void) {
        /* ... */
    }
}

class ViewModel: ObservableObject {
    @Published var data: Int?

    let service: Servicing

    init(service: Servicing) {
        self.service = service
    }

    func fetchData() {
        service.fetchData { [weak self] data in
            self?.data = data
        }
    }
}

class MockedService: Servicing {
    func fetchData(_ completion: @escaping (Int) -> Void) {
        // Mocked Implementation
        DispatchQueue.main.async {
            let randomData = Int.random(in: 0...100)
            completion(randomData)
        }
    }
}

let viewModel = ViewModel(service: MockedService())
Previous
Previous

Discover the Coordinator Pattern

Next
Next

Discover the MVVM Architecture