Search code examples
androiddependency-injectiondagger-2dagger-hilt

Dagger Hilt with multiple implementations of an interface


With Dagger2 it's easy to explicitly create components and list their dependencies. But I can't seem to find a way to provide different implementations of an interface to lets say a fragment.

For example, my app has 2 production modes: paid and free. I have a PaidActivity and a FreeActivity, both of which start exactly the same Dashboard fragment with an Analytics class. For Paid I provide a PaidAnalytics implementation, for Free I provide a FreeAnalytics implementation.

With Dagger2 it's easily achieved by just listing a Paid or a Free Module in the Activity's Component (or Subcomponent).

@Module
abstract class FreeActivityModule {

    @ContributesAndroidInjector(
        modules = [
            FreeAnalyticsModule::class,
            DashboardFragmentModule::class
        ]
    )
    abstract fun injectFreeActivity(): FreeActivity

}

@Module
abstract class PaidActivityModule {

    @ContributesAndroidInjector(
        modules = [
            PaidAnalyticsModule::class,
            DashboardFragmentModule::class
        ]
    )
    abstract fun injectPaidActivity(): PaidActivity

}

@Module
abstract class DashboardFragmentModule {

    @ContributesAndroidInjector
    abstract fun injectDashboardFragment(): DashboardFragment

}

class DashboardFragment : Fragment() {

    ...

    @Inject
    lateinit var analytics: Analytics

    ...

}

With Dagger Hilt I couldn't find a way to do this.


Solution

  • With Dagger it is impossible to replace dependencies at runtime in my use case.

    During one of the Google Hilt sessions they recommended to use an if else statement in a Provides method: https://youtu.be/i27aNF-kYR4?t=3355 (that's what I prefer to avoid).

    The answer above doesn't understand my question, because they are qualifying dependencies at compile time which I can't do. Since my fragment never knows the place it's used and I don't want to just duplicate code.

    Here's an example where you can see exactly what I'm doing and that it can't be achieved with Hilt by design: https://github.com/dmytroKarataiev/daggerAndroidvsHiltRuntimeDependencies