Sandip Fichadiya
Sandip Fichadiya

Reputation: 3480

Dagger 2.10+: Inject dependency with activity context in Activities and Fragments

I have a class called AlertManager which requires Activity instance to show Toast and AlertDialog.

class AlertManager @Inject constructor(private val activity: Activity) {

    fun showToast(message: String) {
        Toast.makeText(activity, message, Toast.LENGTH_SHORT).show()
    }
}

Now, I want AlertManager as dependency in two activities HomeActivity & ProductsActivity. Currently I have created modules for each Activity like:

@Module
class HomeActivityModule {
    @Provides
    @ActivityContext
    fun provideAlertManager(activity: HomeActivity) = AlertManager(activity)
}

And

@Module
class ProductsActivityModule {
    @Provides
    @ActivityContext
    fun provideAlertManager(activity: ProductsActivity) = AlertManager(activity)
}

And binding them with Dagger like

@Module
abstract class ActivityProvider {
    @ContributesAndroidInjector(modules = [HomeActivityModule::class])
    @ActivityContext
    abstract fun bindHomeActivity(): HomeActivity

    @ContributesAndroidInjector(modules = [ProductsActivityModule::class])
    @ActivityContext
    abstract fun bindProductsActivity(): ProductsActivity
}

Now my questions are:

1) How can I avoid creating modules for each activities and have common ActivityModule which I can bind with whatever Activity I want?

2) Let's say I have a fragment called HomeFragment inside HomeActivity, then how can I inject the same AlertManager instance of HomeActivity inside the fragment?

I am stuck here since quite long and have tried to find a lot over internet but I am unable to find any blog or guide which can help me to achieve what I am looking for. If someone can point me in right direction, I'll be grateful.

Upvotes: 4

Views: 2331

Answers (1)

ninad thakare
ninad thakare

Reputation: 99

1) How can I avoid creating modules for each activities and have common ActivityModule which I can bind with whatever Activity I want?

You can have some sort of AlertManagerModule where you add generic activity.

@Provides
fun provideAlertManager(activity: Activity) = AlertManager(activity)

You still will have to make individual activity modules. One change you can make is:

@Module
abstract class HomeActivityModule {
    @Binds
    abstract fun providesActivity(activity: HomeActivity) : Activity
}

And then you can add them to the ActivityProvider class:

@Module
abstract class ActivityProvider {
    @ContributesAndroidInjector(modules = [HomeActivityModule::class, AlertManagerModule::class])
    abstract fun bindHomeActivity(): HomeActivity

    @ContributesAndroidInjector(modules = [ProductsActivityModule::class, AlertManagerModule::class])
    abstract fun bindProductsActivity(): ProductsActivity
}

2) Let's say I have a fragment called HomeFragment inside HomeActivity, then how can I inject the same AlertManager instance of HomeActivity inside the fragment?

Since you're using DaggerActivity and most likely using DaggerFragment, the fragment instantiated in the HomeFragment can directly get the AlertManager by simply using the @Inject annotation in the fragment provided you add in the HomeActivityModule:

 @Module
 abstract class HomeActivityModule {

    @Binds
    abstract fun providesActivity(activity: HomeActivity) : Activity

    @FragmentScope
    @ContributesAndroidInjector
    abstract fun providesHomeFragment() : HomeFragment;
}

Upvotes: 3

Related Questions