Tsudzukeru
@Tsudzukeru

Как правильно создать субкомпонент dagger?

Вот тут (ссылка с таймкодом) ну и в документации говорят, что субкомпонент нужно создавать вот так:

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


теперь мы можем получить заинжектить Factory (MainActivityComponent) прямо в Application class

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


Далее, как я понял, мы можем дергать Factory и создавать субкомпонент в активити. Как то так:

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


Пытаюсь это повторить, но поле типа Factory внутри Application не инджектится и я не могу получить доступ к сабкомпоненту в активити.

Последовательность действий:

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)
    }
}
  • Вопрос задан
  • 159 просмотров
Решения вопроса 1
zagayevskiy
@zagayevskiy Куратор тега Android
Android developer at Yandex
Если это весь код BaseApplication, то конечно же ничего не заинжектится. Магии не бывает, чтобы @Inject поля получили значение, кто-то должен вызвать inject-метод для объекта. У тебя никто этого не делает. Ты должен в AppComponent добавить метод inject (BaseApplication), и вызывать его в onCreate application.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы