Android Dependency Injection

Dependency Injection in Jetpack Compose

Hi everyone!

Hilt, Koin, what dependency injection framework should I pick? Each one has its pros and cons and I won’t discuss all of them in this article, I will show how to use them to inject dependencies in our Compose views.

Hilt

Hilt is the dependency injection framework recommended by Google for Android applications. It is built on top of Dagger, which has been around for several years and adds a lot of boilerplate code to our Android projects. Hilt significantly reduces the amount of boilerplate code required and makes dependency injection very straight forward, however, if you need to inject something into your Compose view (excluding ViewModels), things can get a bit tricky.

I found the documentation for injecting dependencies into Compose very poor, having official documentation for injecting ViewModels only. After doing some research, many people recommend injecting the dependencies in the ViewModel, this seems reasonable when dependencies are related to connecting the domain and presentation layers, but this shouldn’t be exposed to the Compose view component, since a ViewModel is not intended to be a dependency holder.

If you still have Activities and Fragments in your project, you may consider injecting the dependency in the Activity or Fragment and pass it to the Compose function. While this approach looks right, not every project is relying on Fragments, or there are some use cases, such as a Pager, where you have a Composable inside another Composable, each one with its own ViewModel, so it doesn’t make sense to inject all dependencies into the Fragment, pass all of them to the root Composable and then pass the required dependencies to each child.

Getting it right: Hilt EntryPoints

According to Android’s official documentation, Hilt EntryPoint is used to “Obtain dependencies in classes that are either not supported directly by Hilt or cannot use Hilt”. We can create an EntryPoint to define the dependencies we need in our Compose view and then provide them using a Composable function that will use the EntryPoints class to give us access to the EntryPoint.

To inject the dependency into our Composable, we need to call the Compose function we’ve created, that will return the EntryPoint, and get access to the dependency we need.

Koin

Koin is a great alternative to Dagger/Hilt. Its syntax and module creation process are much simpler than Dagger and reduces the boilerplate code as Hilt does. However, it lacks the advantage of just using the @Inject annotation and we need to resolve all the dependencies in the dependency module, just like old-school Dagger, but here we will focus only on how to inject dependencies in Compose.

I’ve found Koin to be way easier to implement than Hilt when working with Compose, it’s like night and day. While you need to create the Hilt EntryPoint to provide the dependency for your Compose view, Koin makes everything simple, and it works out of the box, similar to injecting a ViewModel using Hilt.

Simple — no additional steps are required, and there’s no more boilerplate code. Considering other alternative ways to inject dependencies doesn’t make sense when you have a solution that simple.

Conclusion

While Koin makes everything look very very easy, most of the big projects out there are using Hilt, especially those initially built with Dagger, so I hope we will have official Compose injection with Hilt, similar to how Koin works.

You can access the full code in this GitHub repository. There are two branches, one to cover the Hilt sample and another one for Koin. I hope you enjoyed reading this article. I look forward to your feedback and answering any questions.

Thanks for reading!

Categories

Android

No responses yet

Leave a Reply

Your email address will not be published. Required fields are marked *