https://kotlinlang.org logo
#decompose
Title
# decompose
b

Benjamin Deroche

10/10/2023, 2:44 PM
Hi. I have ViewModels scoped with hiltViewModel in a Compose Destination nav graph. I would like to move to Decompose as I'm really not a huge fan of the API proposed by Compose Destination. How can I integrate my hilt injected viewmodels into Decompose's Components?
a

Arkadii Ivanov

10/10/2023, 3:04 PM
Correct me if I'm wrong, but Hilt (compared to the usual Dagger 2) only adds some nice integration with Android components (like Activity, Fragment, or AAC ViewModel). Since Decompose provides its own replacements, the usual Dagger would work just fine. Or Koin. Or just normal manual DI, when you pass deps via constructors manually. I played with Decompose+Dagger a while ago and it looked nice. Though I don't have any code. Personally, I would use manual DI. But maybe someone could share any info.
b

Benjamin Deroche

10/10/2023, 3:43 PM
You are totally right about Hilt, I could go back to Dagger without much problem as I did the Dagger -> Hilt migration one week ago anyway. My question was more about the ViewModel <-> Component/ComponentContext integration. How do I get my ViewModel, fully injected by Dagger, and tied to its scope provided by Decompose? I fell totally lost between the ViewModelStore/ViewModelStoreOwner/ViewModelProvider/ViewModelFactory/ViewModelProviderFactory... this is just insane.
a

Arkadii Ivanov

10/10/2023, 3:52 PM
I will try to create a sample with Dagger, but this may take some time. Meantime, here is some info. In Decompose, there is no such thing as ViewModel. Instead, there is a generic concept of Instance Retaining. You will find two options. By default, components are recreated on Android configuration change, just like fragments. So you may treat components as a replacement for fragments. And for instance retaining there is
InstanceKeeper
- a replacement for
ViewModelStore
. It manages implementations of
InstanceKeeper.Instance
interface - a replacement for
ViewModel
class. So you implement
InstanceKeeper.Instance
interface, then in a component you call
instanceKeeper.getOrCreate { ... }
. And you basically create your retained instance (aka ViewModel), and here you can supply all dependencies to it. Take care to not leak things from the hosting component! Another approach is to make your components always retained. In this case your components survive configuration changes. And so you don't need
InstanceKeeper
. But you won't be able to pass any dependencies that capture
Context
or
Activity
, etc. into your components.
I have created a sample Decompose+Dagger project: https://github.com/arkivanov/decompose-dagger-sample It doesn't showcase the creation of retained instances (aka ViewModels) with Dagger. But it uses Dagger for creating components, and the same approach can be used for retained instances. Hope this helps.
👀 1
b

Benjamin Deroche

10/12/2023, 1:15 PM
Thank you that helped me quite a lot! If I understood correctly, right now I'm still stuck with Dagger because not all my code base use Decompose. But in the long run, the whole Component tree could pass down the dependencies instead of dagger? It would also be easier to scope certain dependencies or data to a specific part of the Component tree, compared to Dagger's complexity.
a

Arkadii Ivanov

10/12/2023, 1:27 PM
Yeah, with Decompose you can basically call constructors manually and supply dependencies on your own. And so you can scope your deps at certain level. E.g. storing a property in a component means scoping. And you can also use the lifecycle to release resources. You can also use the assisted injection pattern but without Dagger. This may help in cases when you have to pass a dependency to your component only because it is required by a child component (prop drilling).
❤️ 1
b

Benjamin Deroche

10/13/2023, 12:46 PM
Thank you for your help. I think I will stick with it in the future. I'm not a big fan of MVIKotlin as it seems too much overhead for what I need to do so I will stick to MVVM. For navigation, Decompose is also a lot of overhead but it feels like the right solution, way cleaner than Compose Navigation, Compose Destinations or Fragments.
Just wanted to provide my feedback this is the least I can do with all the help you provided
❤️ 1
a

Arkadii Ivanov

10/13/2023, 12:48 PM
You can also take a look at Decompose-Router if you find Decompose cumbersome.
b

Benjamin Deroche

10/13/2023, 12:51 PM
Nah it's fine I'm satisfied with the result but thx for the suggestion
👍 1