Pete Doyle
10/08/2020, 3:04 AM@ContributesAndroidInjector
made it easy to have a module that is scoped to a specific Activity/Fragment, i.e.:
--- AppComponent:
@Singleton
@Component(
modules = [
ActivityBindingModule::class,
AndroidSupportInjectionModule::class,
// ...
]
)
interface AppComponent : AndroidInjector<MyApplication> {
// ...
}
--- ActivityBindingModule:
@Module
internal abstract class ActivityBindingModule {
@ActivityScope
@ContributesAndroidInjector(modules = [MainActivityModule::class]) // MainActivityModule scoped to MainActivity
internal abstract fun mainActivity(): MainActivity
@ActivityScope
@ContributesAndroidInjector(modules = [AnotherActivityModule::class]) // AnotherActivityModule scoped to AnotherActivity
internal abstract fun anotherActivity(): AnotherActivity
}
--- MainActivityModule:
@Module
abstract class MainActivityModule {
@FragmentScope
@ContributesAndroidInjector(modules = [SignInFragmentModule::class])
internal abstract fun signInFragment(): SignInFragment
@FragmentScope
@ContributesAndroidInjector
internal abstract fun whatsNewFragment(): WhatsNewFragment
@FragmentScope
@ContributesAndroidInjector
internal abstract fun settingsFragment(): SettingsFragment
}
Is something similar possible in HIlt? Or is there another strategy that might be similar? (random: if not, maybe in
It seems like MainActivityModule and AnotherActivityModule would both use @InstallIn(ActivityScoped::class)
, then both MainActivity and AnotherActivity could @Inject
from either (I might be missing something?).
Similarly, is it possible to have a setup where Fragments could @Inject
things from their host Activity’s module? (e.g. in the above example, SignInFragment could inject anything from AppComponent, MainActivityModule, and SignInFragmentModule.
We’ve taken advantage of this property of Dagger-Android, and I’m currently not quite sure what a migration to Hilt would look like.Ahmed Ibrahim
10/08/2020, 12:04 PM@InstallIn(FragmentComponent)
and will be able to access anything from ActivityComponent
till SingletonComponent
Ahmed Ibrahim
10/08/2020, 12:07 PMBrady Aiello
10/10/2020, 9:33 PMBrady Aiello
10/10/2020, 9:35 PMPete Doyle
10/11/2020, 7:10 AM@InstallIn(ActivityScoped::class)
)
however;
It doesn’t seem straightforward that:
• Activity X (and Fragments X1, X2) can have dependency B (B@1234)…
• Without also allowing Activity Y (and Fragments Y1, Y2) to have dependency B (B@6789).
i.e. for screens that might have large dependencies (memory usage, startup time, etc) that only make sense for one feature, it doesn’t seem straightforward to make those dependencies only available to one screen (is super simple in Dagger-Android, for better or worse).
Could possibly make them Lazy
and Dagger just wouldn’t create them if they’re never `@Inject`ed from Activity Y (and/or Fragments Y1/Y2)?
Realistically, I think this isn’t that limiting. So far it seems like my team has used a few @Binds
so we can inject Activity
in certain places, Doesn’t seem straightforward to do the same in Hilt. That’s probably an anti-pattern anyways, and worth breaking.
I’m not really sure the above is right, but it seems like it so far. 🙂Pete Doyle
10/11/2020, 7:54 AM… A polylithic system is the default mode when using dagger.android’s. This page goes through some of the reasons Hilt was designed using monolithic components along with tradeoffs between the two models.@ContributesAndroidInjector
… Polylithic components give you more flexibility to define different bindings per activity, but this usually ends up making things more confusing as code bases become larger and harder to trace.
For keeping bindings private to only code that should use them, we recommend using qualifier annotations that are protected through restricted visibility or using an SPI plugin to enforce separation of code.