Tsudzukeru
@Tsudzukeru

Как выполнить DI в Activity, используя dependencies?

Есть приложение состоящее из класса App и Activity. У каждого класса есть модуль, который предоставляет строку:

@Module
class AppModule {

    @Named("app string")
    @Provides
    fun provideSimpleString(): String {
        return "Dagger app string"
    }
}


@Module
class ActivityModule {

    @Named("activity string")
    @Provides
    fun provideSimpleString(): String {
        return "Dagger activity string"
    }
}


Так же соответственно есть два компонента:

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

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


@ActivityScope
@Component(dependencies = [AppComponent::class], modules = [ActivityModule::class])
interface ActivityComponent {

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

    fun inject(mainActivity: MainActivity)
}


Классы Activity и App
class App : Application() {
    lateinit var appComponent: AppComponent

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


class MainActivity : AppCompatActivity() {
    @Inject
    @Named("app string") lateinit var appString: String
    @Inject
    @Named("activity string")lateinit var activityString: String

    lateinit var activityComponent: ActivityComponent

    override fun onCreate(savedInstanceState: Bundle?) {
        activityComponent = DaggerActivityComponent.factory().create()
        activityComponent.inject(this)
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        Log.i(TAG, "onCreate: $appString")
        Log.i(TAG, "onCreate: $activityString")
    }

    companion object {
        private const val TAG = "MainActivity"
    }
}


Ошибка сборки.
error: @Component.Factory method is missing parameters for required modules or components: [com.app.di.di.AppComponent]

Переписываю activityComponent() на следующий:
@ActivityScope
@Component(dependencies = [AppComponent::class], modules = [ActivityModule::class])
interface ActivityComponent {

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

    fun inject(mainActivity: MainActivity)
}


Переписываю activity:
class MainActivity : AppCompatActivity() {
    @Inject
    @Named("app string") lateinit var appString: String
    @Inject
    @Named("activity string")lateinit var activityString: String

    lateinit var activityComponent: ActivityComponent
    lateinit var appComponent:AppComponent

    override fun onCreate(savedInstanceState: Bundle?) {
        appComponent = (application as App).appComponent
        activityComponent = DaggerActivityComponent.factory().create(appComponent)
        activityComponent.inject(this)
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        Log.i(TAG, "onCreate: $appString")
        Log.i(TAG, "onCreate: $activityString")
    }

    companion object {
        private const val TAG = "MainActivity"
    }
}


Теперь другая ошибка сборки:

/home/x/GIT/DI/app/build/tmp/kapt3/stubs/debug/com/app/di/ui/activity/ActivityComponent.java:8: error: [Dagger/MissingBinding] javax.inject.Named("app string") java.lang.String cannot be provided without an @Provides-annotated method.
  • Вопрос задан
  • 185 просмотров
Решения вопроса 1
zagayevskiy
@zagayevskiy Куратор тега Android
Android developer at Yandex
Чтобы это работало, в компоненте зависимостей должны быть явные provision-методы(геттеры) для всего, что должно попасть в граф другого компонента. В твоём случае надо добавить в AppComponent метод
@Named("app string")
 fun appString(): String
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

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