Dagger 2错误:没有@Inject构造函数的依赖"无法提供"

Squ*_*yMo 3 android dependency-injection kotlin dagger-2

我正在尝试在我的Android项目中使用Dagger 2.对于初学者,我想分别使用两个负责注入应用程序范围和活动范围依赖关系的组件.作为基本参考,我使用了这个答案.

因此,有两种不同的方法来设置组件之间的关系:使用@Subcomponent注释和dependencies参数.

  1. 如果我选择第一个,我的AppContextComponent工作正常.但是一旦我尝试从中注入依赖项ActivityContextComponent,我就会遇到这个构建时错误:

错误:如果没有@Inject构造函数或@ Provide-或@ Produces-annotated方法,则无法提供com.example.ui.activity.MainActivity.

  1. 使用第二种方法,我得到所有依赖项的此错误.

知道我确实有提供方法,这个错误信息坦率地没用.以下是我设法谷歌出错的其他几个可能的错误来源,但似乎并非如此:

  1. 范围问题.
  2. 由于来自不同提供方法的相同返回类型导致的不确定性(即使我删除提供的方法,问题仍然存在Context).

以下代码在Kotlin中,但我认为它应该非常简单.

应用程序组件

object AppContext {
    // a singleton used in place of a Java static field
    @JvmStatic lateinit var graph: AppContextComponent
}

@ApplicationScope @Component(modules = arrayOf(AppContextModule::class))
interface AppContextComponent {
    fun inject(fragment: BaseFragment)

    fun newActivityContextComponent(module: ActivityContextModule): ActivityContextComponent
}

@Module
class AppContextModule(val app: MyApplication) {
    @Provides @ApplicationScope @ForApplication
    fun provideContext(): Context {
        return app;
    }

    @Provides @ApplicationScope
    fun provideMyApplicationContext(): MyApplication {
        return app;
    }
}
Run Code Online (Sandbox Code Playgroud)

活动组件

object ActivityContext {
    @JvmStatic lateinit var graph: ActivityContextComponent
}

@ActivityScope @Subcomponent(modules = arrayOf(ActivityContextModule::class))
interface ActivityContextComponent {
    fun inject(fragment: BaseFragment)
}

@Module
class ActivityContextModule(val activity: MainActivity) {

    // Worth pointing out is that the provision methods are not used. 
    // That is, no code is being generated for them.

    @Provides @ActivityScope @ForActivity
    fun provideContext(): Context {
        return activity;
    }

    @Provides @ActivityScope
    fun provideMainActivityContext(): MainActivity {
        return activity;
    }
}
Run Code Online (Sandbox Code Playgroud)

以下是这些组件的使用方法.

应用

class MyApplication : SugarApp() {
    override fun onCreate() {
        super.onCreate()
        AppContext.graph =
            DaggerAppContextComponent
                    .builder()
                    .appContextModule(AppContextModule(this))
                    .build()
    }
}
Run Code Online (Sandbox Code Playgroud)

活动

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ActivityContext.graph = 
            AppContext.graph
                 .newActivityContextComponent(ActivityContextModule(this))
    }
}
Run Code Online (Sandbox Code Playgroud)

BaseFragment(实际注入发生的地方)

abstract class BaseFragment : Fragment() {
    // works fine
    @Inject @ForApplication lateinit var myApplication: MyApplication

    // fails with "cannot be provided" error
    @Inject @ForActivity lateinit var myActivity: MainActivity

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ActivityContext.graph.inject(this)
    }
}
Run Code Online (Sandbox Code Playgroud)

我错过了什么?

谢谢!

And*_*dEx 10

编辑

要点是:

如果你使用dagger的@Subcomponents,请确保你没有在@Component子组件中注入与子组件相同的目标类的方法.

Dagger会感到困惑,并会尝试生成直接从父组件注入目标的代码,而它没有满足注入依赖项所需的模块.