Dependency Injection Made Easy

Episode #16 • May 21, 2018 • Subscriber-Only

Today we’re going to control the world! Well, dependencies to the outside world, at least. We’ll define the “dependency injection” problem and show a lightweight solution that can be implemented in your code base with little work and no third party library.

Dependency Injection Made Easy
Introduction
00:05
An example application
01:03
Dependency injection
04:25
Controlling time
09:40
Current
17:02
Controlling the world
19:25
One less protocol
21:15
One more dependency
25:55
What’s the point?
31:10

Unlock This Episode

Our Free plan includes 1 subscriber-only episode of your choice, plus weekly updates from our newsletter.

Introduction

Today we’re going to revisit a topic we’ve talked about in the past: side effects. We introduced the topic in our second episode with a deep dive on how side effects are kind of like hidden inputs and outputs to our functions, demonstrating how they make testing difficult and how they can introduce subtle bugs. Side effects are complicated and require attention.

The examples in that episode were a bit contrived, so today we’re going to look at code that’s a bit more real-world and explore how we can extract and control side effects quickly and painlessly.

This is a method we’ve used in production again and again, and it’s proven itself over time. We hope that others get the same benefit!

This episode is for subscribers only.

Subscribe to Point-Free

Access this episode, plus all past and future episodes when you become a subscriber.

See plans and pricing

Already a subscriber? Log in

Exercises

  1. Today’s episode was powered by playground-driven development, but we’re talking about real-world code and that kind of code usually lives in an application target. The following exercises explore how to apply playground-driven development to actual application code.

    1. Download the episode code and copy it into a new iOS project called “Repos”. The app should display the repos navigation controller as the window’s root view controller.

    2. Add a framework target to the project called “ReposKit” and embed it in the Repos app. Move all of our application code (aside from the app delegate) to ReposKit. Make sure that the source files are members of the framework target, not the app target. Repos should import ReposKit into the app delegate in order to access and instantiate the ReposViewController. Build the application to make sure everything still works (you will need to make some types and functions public).

    3. Create an iOS playground and drag it into your app project. Import ReposKit, instantiate a ReposViewController, and set it as the playground’s live view. You can use our original playground code as a reference.

    4. Swap out the Current, live world for our mock one. This playground page can now act as a living reference for this screen! You can modify the mock to test different states, and to test changes to the view controller, you can rebuild ReposKit.

  2. There are a few dependencies in the application that we didn’t cover. Let’s explore controlling them over a couple exercises.

    1. The analytics client is calling out to several singletons: Bundle.main, UIScreen.main, and UIDevice.current. Extract these dependencies to Environment. What are some advantages of controlling these dependencies?

    2. DateComponentsFormatter can produce different strings for different languages and locales, but defaults to the device locale. Extract this dependency to Environment, control it on the formatter, and demonstrate how mocking Current allows you to test formatting over different languages and locales.

References

Structure and Interpretation of Swift Programs

Colin Barrett • Tuesday Dec 15, 2015

Colin Barrett discussed the problems of dependency injection, the upsides of singletons, and introduced the Environment construct at Functional Swift 2015. This was the talk that first inspired us to test this construct at Kickstarter and refine it over the years and many other code bases.

How to Control the World

Stephen Celis • Monday Sep 24, 2018

Stephen gave a talk on our Environment-based approach to dependency injection at NSSpain 2018. He starts with the basics and slowly builds up to controlling more and more complex dependencies.

Downloads