Kotlin的匕首2范围和依赖

时间:2018-02-17 01:28:21

标签: android dependency-injection dagger-2 dagger

我希望将Dagger 2添加到现有的应用程序中,并且遇到组件依赖性和范围问题,一旦我得到更多的2级别。我的思维过程是使用AppComponentLandingActivityComponent范围LandingFragmentComponent@Singleton@ActivityScope(现在不是很棒的名字,但我们很早)和@FragmentScope分别。如果我停止活动,我所做的一切都有效,但是一旦我添加了片段级别,我就会收到以下错误:

e: /Users/me/git/myapp-android/myapp/build/tmp/kapt3/stubs/regularDebug/tv/myapp/android/app/core/dagger/LandingActivityComponent.java:17: error: com.myapp.android.app.core.LandingActivity cannot be provided without an @Inject constructor or from an @Provides-annotated method. This type supports members injection but cannot be implicitly provided.
    public abstract com.myapp.android.app.core.LandingActivity landingActivity();
                                                               ^
      com.myapp.android.app.core.LandingActivity is provided at
          com.myapp.android.app.core.dagger.LandingActivityComponent.landingActivity()
e: /Users/me/git/myapp-android/myapp/build/tmp/kapt3/stubs/regularDebug/tv/myapp/android/app/core/dagger/LandingFragmentComponent.java:13: error: com.myapp.android.app.settings.QuickSettingsPresenter cannot be provided without an @Inject constructor or from an @Provides- or @Produces-annotated method.
    public abstract void inject(@org.jetbrains.annotations.NotNull()
                         ^
      com.myapp.android.app.settings.QuickSettingsPresenter is injected at
          com.myapp.android.app.profile.ProfileViewPagerFragment.mQuickSettingsPresenter
      com.myapp.android.app.profile.ProfileViewPagerFragment is injected at
          com.myapp.android.app.core.dagger.LandingFragmentComponent.inject(profileViewPagerFragment)

应用

@Module
class AppModule(private val app: MyApplication) {

    @Provides @Singleton
    fun provideApp(): MyApplication = app

    @Provides @Singleton
    fun provideContext(): Context = app.applicationContext

    @Provides @Singleton
    fun provideAccountManager(): AccountManager = AccountManager(app)
}

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

    fun inject(application: MyApplication)

    // Allow dependents to see the properties provided below
    fun accountManager(): AccountManager
}

活动

@Scope
@Qualifier
@Retention(RUNTIME)
annotation class ActivityScope

@Module
class LandingActivityModule(private val landingActivity: LandingActivity) {

    @Provides @ActivityScope
    fun provideLandingActivity(): LandingActivity = landingActivity
}

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

    fun inject(landingActivity: LandingActivity)

    // Allow dependents to see the properties provided below
    fun landingActivity(): LandingActivity
    fun accountManager(): AccountManager
}

片段

@Scope
@Qualifier
@Retention(RUNTIME)
annotation class FragmentScope

@Module
class LandingFragmentModule(private val landingFragment: LandingFragment) {

    @Provides @FragmentScope
    fun provideFragment(): LandingFragment = landingFragment

    @Provides @FragmentScope
    fun provideQuickSettings(activity: LandingActivity): QuickSettingsPresenter =
            QuickSettingsPresenter.create(activity)
}

@FragmentScope
@Component(dependencies = [LandingActivityComponent::class], modules = [LandingFragmentModule::class])
interface LandingFragmentComponent {

    fun inject(profileViewPagerFragment: ProfileViewPagerFragment)
}

我觉得我可能错过了一些基本的东西,或者需要以不同的方式构建事物,但我认为这突出了我的目标。

有趣的是,如果我删除活动和片段模块中@Scope的{​​{1}}注释,一切都很好。正如我所提到的,如果我剪切出片段模块,我可以将活动范围没有问题。

这里的最终目标是让这些组件与演示者合作,但我有点一步一步走。我是Dagger的非单片组件的新手,并没有找到一个指向我的点击的指南或帖子。

1 个答案:

答案 0 :(得分:0)

(代表作者提问)

我弄明白发生了什么。在某个地方,我读到的东西让我相信我需要@Qualifier作为我的范围的一部分但事实并非如此。删除它似乎解决了我的问题。将此作为基于依赖的方法留给任何人看。