czwartek, 3 grudnia 2015

Dependency Carrying in Swift (with storyboards)

Every programmer must've struggled with Dependency Carrying, even though he might've not known that it has it's own name. Dependency Carrying is extremely uncomfortable, when you have a lot of dependencies and you have to pass them deeper through the object tree. You have to define the same code for each class in the hierarchy - there must be a different way, right ?

View Controllers are actually a great example. Let's say that you have a Navigation Controller that navigates between 20 different View Controllers. If you have a database context, a networking context, you have to inject it manually into all of the controllers. What if you have 6 or 8 dependencies ? That's a lot of copy and paste injection code. What I usually did was refactor the dependencies into an aggregate and create different interfaces for that aggregate, but there must be an easier way to manage your dependencies, right ?


I usually avoid using any dependency frameworks, because it just seems too extreme for me to have a library in your project just for a design pattern, but maybe I was wrong ? Let's try and use a dependency injection framework and see how it solves our problem.

The only reason I decided to test this approach is because Swinject is so easy and lightweight. You don't need any configuration files and it supports storyboards, which is awesome!

Let's create a new project with a storyboard and two view controllers.

Now let's create an separate file, an extension for Swinject that will run when setting up the storyboard.

That's it! Your view controllers will now be injected with the objects you've registered. I must say that I really liked it. It's very easy, you configure everything in one file and in Swift and it works great with storyboards. The code isn't very elegant, but if you have 20 view controllers you can just use a function that will inject needed dependencies depending on the view controllers protocol.

One more awesome thing: your view controllers are ready to unit test! Well, not really in my example, because I didn't obscure concrete classes with protocols, so I can't mock, but if you do, you can register a different class configuration in your unit tests and you're ready to go!

Swinject has a lot of different features that you can leverage, so you should definitely check it out!

There's very little code (that's good!), but if you want to check out how it's all connected here's the repo.