Dependency injection without frameworks
This post is one of those ones that I’ve been wanting to write for a while. It was some days ago when, by coincidence, I was reading a post about dependency injection at the same time that a coworker came to talk with me about the topic.
The main idea that I wanted to express was:
You don’t need a framework to do dependency injection.
This is one of these small things that drives me crazy. Reading any introductory post about dependency injection with the only purpose of selling you a framework. That makes people think that dependency injection is something that you need a framework for, that after setting up some configuration you can call some methods on the framework and... magic happens.
And that’s so far from the truth.
That's why I liked this post on dependency injection in Swift: Introduction to Swinject. Because although it sells you the framework, is the last thing that does.
In the example it shows you how to do DI:
PetOwner(pet: Cat(name: "Mimi"))
That’s all. You inject the
AnimalType into the
PetOwner instead of having the last one create the animal by itself.
This allows you to inject any other animal:
PetOwner(pet: Dog(name: "Hachi"))
Easy has that. You don't need anything else!
As I was telling my co-worker to take a look at how
PetOwner is implemented. I’ve seen a lot of people having, in situations like this, a getter for the animal where it uses the DI framework (change PetOwner for VC or VM and the animal for some kind of source of data). This is not what you should do. Instead, it accepts an animal from the outside, and in the outside is where the DI framework is used for convenience. This makes your code, the PetOwner in this case, completely agnostic of any DI framework.
This last part is pretty important. I’m not saying that you shouldn’t use a framework. I’ve done it by hand in some Apps and, to be honest, there is nothing wrong with it. But I understand that you probably want something more cool. In that case, use it, but keep in mind that your code should be agnostic of the framework that you choose.
If you use DI only for the sake of testing you are only hiding the problem. You are decoupling your code from a concrete implementation of a dependency by adding a new, bigger, and probably less known, dependency. Good luck for your future self.
To finish, let me repeat the two important ideas that you should take from this post:
- There is NO need for a framework, you can do Dependency Injection just by passing any dependency as a parameter.
- You can use a framework for convenience, but don’t pollute your app with it.