Reusing Hilt Fragment (or other Hilt injection targets)

47 Views Asked by At

I'm working an an app that heavily reuses a Fragment that implements a partial server driven UI, and I'm trying to asses if Hilt is an option to replace Dagger Android for us. I've searched around and I can't really find anything, and my opinion is that this is not really possible in Hilt, but I'm giving it a try here - maybe I'm missing something.

Almost all the screens in our app are exactly the same fragment that's injected using different implementations of its dependencies. To make this work in Dagger Android, the reused fragment is abstract and we create simple subclasses of it just to create different injection scopes:

abstract class HeavilyReusedFragment ...

class HeavilyReusedFragment1 : HeavilyReusedFragment() ...
class HeavilyReusedFragment2 : HeavilyReusedFragment() ...

@Module
abstract class HeavilyReusedFragment1Injector {
    @ContributesAndroidInjector(modules = [1's dependencies])
    abstract fun injectHeavilyReusedFragment1(): HeavilyReusedFragment1
}

@Module
abstract class HeavilyReusedFragment2Injector {
    @ContributesAndroidInjector(modules = [2's dependencies])
    abstract fun injectHeavilyReusedFragment2(): HeavilyReusedFragment2
}

Now, trying to do this in Hilt would result in multiple binding errors for all the dependencies since all of them would be registered in the exact same component (FragmentComponent). The only option that I see, which looks very bad if one has a lot of dependencies, is to do a switch statement in Dagger based on the fragment class, something like:

@Module
@InstallIn(FragmentComponent::class)
abstract class HeavilyReusedFragmentInjectorModule {
    @Provides
    fun provideDep1(fragment: Fragment): Dep1 = 
        when (fragment)  {
            is HeavilyReusedFragment1 -> Dep1Impl0()
            is HeavilyReusedFragment2 -> Dep1Impl1()
        }
}

Even thinking about this in Compose does not seem to solve the problem. Let's say we have a Composable that's reused, its ViewModel being instantiated with different repositories and different dependency implementations. How would someone go about to creating these differently configured ViewModels implementations? Create subclasses of a base abstract ViewModel and wrapper Composables that depend on different ViewModel subclasses? I still don't know how to the factory for those ViewModels would be injected if the base ViewModels depends on interfaces and not concrete implementations - there would need to be a lot of switch statements.

I'm not sure if I'm not able to find it or it's just that no one is trying to reuse code configured differently through injection in Android - which seems very strange.

0

There are 0 best solutions below