(Pretty sure the answer is no, but wanted to doubl...
# dagger
p
(Pretty sure the answer is no, but wanted to double-check https://dagger.dev/hilt/migration-guide.html#be-aware-of-differences-with-monolithic-components) In Dagger-Android,
@ContributesAndroidInjector
made it easy to have a module that is scoped to a specific Activity/Fragment, i.e.:
Copy code
--- 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.
a
If I understood correctly, yeah it's possible, you'll have to install the appropriate module to the correct component. For example SignInFragmentModule would have
@InstallIn(FragmentComponent)
and will be able to access anything from
ActivityComponent
till
SingletonComponent
Dagger Android and Hilt both follow the same approach of doing things in terms of installing modules in Subcomponents rather than individual components. But Hilt made it much streamlined by providing a predefined set of components for you to install your modules in.
Much easier to do that now with Hilt. No more manually making custom scopes for every Activity.
p
Awesome, thanks @Brady Aiello 🙂 I think what I’m after is that, with respect to this: https://twitter.com/manuelvicnt/status/1281299035115139072?s=20 I think it’s clear that: • Activity X (and it’s fragments X1, X2) can have their own instance of dependency A (A@1234), and: • Activity Y (and it’s fragments Y1, Y2) will have their own instance of dependency A (A@6789) (i.e. via
@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. 🙂
Found this, makes it clear: 🙂 https://dagger.dev/hilt/monolithic.html
… A polylithic system is the default mode when using dagger.android’s 
@ContributesAndroidInjector
. This page goes through some of the reasons Hilt was designed using monolithic components along with tradeoffs between the two models.
… 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.