jetc.dev Newsletter Issue #33
This week, we continue banging the drum for using immutable types with Compose. We also look at Hilt and GraphQL with Compose, and we explore how dependency inversion might work with a Compose-based UI. We also watch a Compose-rendered T-Rex run and jump!
One Off the Stack, One Off the Slack
You’ve got questions. That’s understandable!
This week’s options for Stack Overflow questions mostly were incomplete, so let’s focus on Slack instead…
Hardly a week goes by without somebody being bitten in the posterior by trying to use mutable data with Compose. While Compose can use mutable properties and types, they may not trigger recompositions when you mutate their contents. On the whole, Compose works better with immutable types, as we see in this week’s highlighted Slack thread.
Posts, videos, and other new information related to Jetpack Compose!
100% pure code!
Koin is a dependency inversion (DI) system written in Kotlin, used as an alternative
to Dagger. The current pre-release build of Koin offers dependency resolution from
within a composable, both for arbitrary Koin-supplied objects and specifically for
instances. For those looking to perhaps use Compose in Kotlin/Multiplatform
projects, Koin is an important option, given that it supports KMP while Dagger is
tied exclusively to the JVM.
…And One More Thing
There are many aspects of modern Android app development that we need to work into
Compose-based development. Dependency inversion (DI) is one of those.
While a lot of DI takes place away from the UI layer, modern activities and fragments
still often use some amount of DI, such as for obtaining configured
instances. So we need to determine where in a composable hierarchy we should be
using DI… if anywhere.
Koin’s release of composable DI support, mentioned earlier in this issue, sparked some discussion on this point. Some developers believe that composables should not be interacting with DI services — instead, they should be getting all injectable elements passed into them instead.
Personally, I am skeptical of that argument, for the simple reason that
@Composable annotation is going to be everywhere.
For example, once a Compose-ready edition of the Jetpack Navigation component is ready, my guess is that our Compose activity will look like:
setContent()with a composable lambda, as we have it now
That lambda will set up Navigation using the Kotlin DSL
Nav destinations will be calls to composable functions
This does not preclude limiting DI to being outside of the composable hierarchy. But that means everything that we are getting from DI that is needed by the UI layer goes in this activity. That seems excessive, particularly for larger apps.
My guess is that we will adopt DI patterns reminiscent of how we handle state. Right now, the state recommendations are:
Prefer stateless composables to stateful ones, particularly at leaves of the composable hierarchy
For composables that need state, prefer to receive the state via parameters rather than declaring it locally
Aim to have your state at the point of commonality: the spot in the composable hierarchy where all consumers of that state descend from
So, for DI, we might wind up with:
Prefer composables without DI-provided dependencies, particularly at leaves of the composable hierarchy
For composables that need dependencies, prefer to receive them via parameters rather than having it be injected locally
Aim to have your injections at the point of commonality: the spot in the composable hierarchy where all consumers of that dependency descend from
But, that is what the next several months are for, as we progress through alpha releases and “kick the tires” on Compose. By the time Compose ships in stable form — and preferably even before a beta — hopefully we will have a pattern that seems reasonable that we can provide to newcomers.
- 2023-01-24: Locales! Relay! Effects! Paging! Foldables! Permissions! Date pickers! Bi-directional scrolling! And what your MaterialTheme means... for your SwiftUI code?!?
- 2023-01-17: New Compose patches and alphas! Dealing with Navigation for Compose! Scaffolds! QR codes! Server-defined UI! And @firstname.lastname@example.org has joined the BOM squad! 😁 💥
- 2023-01-10: onNewIntent() and composables! ContactsContract and composables! Balloons! QR codes! Pencils! And a focus on focus!