T
T
Tsuzukeru2021-05-07 16:29:18
Android
Tsuzukeru, 2021-05-07 16:29:18

How to properly create a dagger subcomponent?

Here (link with timecode ) well, the documentation says that the subcomponent should be created like this:

@Module(subcomponents = [MainActivityComponent::class])
interface AppModule{}


now we can get to inject the Factory (MainActivityComponent) directly into the Application class

class App : Application() {
@Inject 
lateinit var mainActivityComponentFactory:MainActivityFeatureComponent.Factory
}


Further, as I understand it, we can pull the Factory and create a subcomponent in the activity. Something like this:

override fun onCreate(savedInstanceState: Bundle?) {
        (application as App).mainActivityComponentFactory.create().inject(this)
        super.onCreate(savedInstanceState)
    }


I'm trying to repeat this, but the Factory type field inside the Application is not injected and I can't access the subcomponent in the activity.

Workflow :

AppComponent
@Singleton
@Component(modules = [AppModule::class])
interface AppComponent {

    @Component.Factory
    interface Factory {
        fun create(): AppComponent
    }

    fun getPreviewComponent(): PreviewComponent.Factory
    fun getDetailComponent(): DetailComponent.Factory
//    fun getActivityComponent():ActivityComponent.Factory
    fun getSearchSettingsComponent():SearchSettingsComponent.Factory
    fun getDownloadFilesComponent():DownloadFilesComponent.Factory
}


AppModule
@Module(subcomponents = [ActivityComponent::class])
class AppModule {

    @Singleton
    @Provides
    fun provideNasaApiService() :NasaApiService {
     ...
    }

    @Singleton
    @Provides
    fun providePicassoInstance(): Picasso {
        return Picasso.get()
    }

    @Singleton
    @Named("initial media previews")
    @Provides
    fun provideInitialMediaPreviewResponseMutableLiveData(): MutableLiveData<MediaPreviewResponse> {
        return MutableLiveData<MediaPreviewResponse>()
    }
}


Application
class BaseApplication : Application() {
    lateinit var appComponent: AppComponent

    @Inject
    lateinit var activityComponentFactory:ActivityComponent.Factory

    override fun onCreate() {
        super.onCreate()
        appComponent = DaggerAppComponent.factory().create()
    }
}


ActivityComponent
@Subcomponent
interface ActivityComponent {

    @Subcomponent.Factory
    interface Factory {
        fun create(): ActivityComponent
    }

    fun inject(mainActivity: MainActivity)
}


MainActivity
class MainActivity : AppCompatActivity(), Activity {
    @Inject
    lateinit var searchParams: SearchParams

    override fun onCreate(savedInstanceState: Bundle?) {
        (application as BaseApplication).activityComponentFactory.create().inject(this)
        super.onCreate(savedInstanceState)
    }
}

Answer the question

In order to leave comments, you need to log in

1 answer(s)
D
Denis Zagaevsky, 2021-05-07
@Tsuzukeru

If this is all BaseApplication code , then of course nothing will be injected. There is no magic for @Inject fields to get a value, someone has to call the inject method on the object. Nobody does it for you. You must add the inject (BaseApplication) method to the AppComponent and call it in the onCreate application.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question