Skip to content

Chapter 5. Dependency Injection.

Dmitriy Shulzhenko edited this page Sep 27, 2020 · 3 revisions

The DI principles we use at Headway are simple:

  • implementation knows only interface
  • only Factory knows about others and other Factories

Here are some examples of how components are created:

Simple protocol just to make our code consistent

protocol StaticFactory {
    associatedtype Factory
}

Factory for TMDBApi knows how to create itself. It is also stored as static instance.

extension TMDBApi: StaticFactory {
    enum Factory {
        static let `default`: TMDBApiProvider = TMDBApi()
    }
}

Factory for MovieDetailDriver knows how inject TMDBApiProvider.

extension MovieDetailDriver: StaticFactory {
    enum Factory {
        static func `default`(id: Int) -> MovieDetailDriving {
            MovieDetailDriver(id: id, api: TMDBApi.Factory.default)
        }
    }
}

Factory for MovieDetailViewController initialises all of the components above.

extension MovieDetailViewController: StaticFactory {
    enum Factory {
        static func`default`(id: Int) -> MovieDetailViewController {
            let vc = R.storyboard.main.movieDetailViewController()!
            let driver = MovieDetailDriver.Factory.default(id: id)
            let stateBinder = MovieDetailStateBinder(viewController: vc, driver: driver)
            let actionBinder = MovieDetailActionBinder(viewController: vc, driver: driver)
            let navigationBinder = NavigationPopBinder<MovieDetailViewController>.Factory
                .pop(viewController: vc, driver: driver.didClose)
            vc.bag.insert(
                stateBinder,
                actionBinder,
                navigationBinder
            )
            return vc
        }
    }
}

Notice that there is no initialisation code inside of the components.

Clone this wiki locally