Edward Harker

Dead Simple Dependancy Injection

Dependancy injection allows us to loosely couple classes and test them in isolation. We do this by passing the dependancies of a class into its constructor.

class AccountPresenter(
    private val userRepository: UserRepository
)

This is super simple. Things get more complicated when building the dependency graph and this is where many developers turn to frameworks. But ‐ it doesn’t have to be this way.

object AccountPresenterInjector {
    fun accountPresenter() = AccountPresenter(
        userRepository = userRepository()
    )
}

We can create an Injector for each class or interface. The Injector is responsible for building an object by calling the injectors of each dependancy. Essentially, we have a static factory to create our object.

At some point, we’re in a class where we don’t own the constructor (eg. a main method or Android Activity) and we can call the injector to get the object that we want.

class AccountActivity : Activity() {
    private val accountPresenter = accountPresenter()
}

This is a really simple approach to dependancy injection. We’ve replaced annotations and magic with static factories. No more cryptic build errors or slow annotation processing. It’s easy for anyone to understand, as it’s all plain kotlin code. It might be more boilerplate code to write, but I think that for many projects the benefits are worthwhile.