How to do clean dependency injection using Firebolt — Swift.

Andrew Aquino
3 min readJul 25, 2020

What is dependency injection? In its most basic sense, dependency injection is the act of inserting values inside another object instead of the object itself creating those values from the inside, you “inject” these values so to speak.

It’s pretty easy to implement dependency injection but at scale it gets pretty cumbersome. Consider this example,

ClassB depends on ClassA

As you can see, ClassB depends on ClassA for it to be initialized. When you’re creating these classes in your code it is easy is do something like this,

However, as your growing your application your dependencies become much more complex, sooner or later you’re going to have classes that look like this,

What happens if you want to create ViewController multiple times? That would be a lot of duplicated code and prolonged sessions of distraught finger banging.

That’s where a dependency resolver comes in. Dependency resolvers are essentially chefs that have a menu of dishes you like to get. Since most dishes are a conglomeration of complex mixes of spices and other dishes. You can kind of see how even something like a Lasagna would be difficult to make (at least for me). You can think of dependency resolvers as something that has a menu of dishes that you know and love and it knows how to create each one for you without any effort on your end.

In this case a good dependency resolver will turn something like this to this,

In fact, now you can create as many ViewController's as you want since they are resolved by the resolver for you. Now that’s great catering!

There are many dependency resolvers out in the Swift world, but in my opinion there wasn’t really anything out there that really stood out to me. Most of them had pretty opinionated setup code, some of their interfaces weren’t intuitive, and all of them didn’t manage instances and scope as nicely as I would like when I started making session-based application where a User is able to switch between different accounts and the application is able to clean up all the dependencies of the previous user and recreate new ones essentially preserving the application’s atomicity. There are also many ways dependencies are resolved such as using reflection, factory patterns, or functional patterns; my favorite is the latter as it is the least intrusive and more straight forward.

After diving into Kotlin for the remainder of my time at Bird and writing mostly backend code and some Android. I eventually found a functionally resolving dependency resolver called Koin and my god not only is the style of Kotlin so intuitive but this library’s interface and usage was as well.

I introduce to you, Firebolt https://github.com/DrewKiino/Firebolt

It is the Swift’s answer to Kotlin’s Koin and has support scoping, arguments, protocol & opaque conformances, synchronous thread safety, global resolutions, multiple resolvers, subclass-able resolvers, and fine-grained dependency management per resolver such as registering, unregistering, caching, and more.

Here is an example of using Firebolt

There’s a lot more to Firebolt than the above example but this should give you a good idea of how clean and simple it is to use.

Happy coding!

--

--

Andrew Aquino

Entrepreneur / Senior Full-Stack Software Engineer