android - Dagger 2 错误 : dependency “cannot be provided without an @Inject constructor”

标签 android dependency-injection kotlin dagger-2

我正在尝试在我的 Android 项目中使用 Dagger 2。对于初学者,我想使用两个组件分别负责注入(inject)应用程序范围和 Activity 范围的依赖项。作为基本引用,除其他外,我使用了 this answer .

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

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

Error:com.example.ui.activity.MainActivity cannot be provided without an @Inject constructor or from an @Provides- or @Produces-annotated method.

  1. 使用第二种方法时,所有依赖项都会出现此错误。

知道我确实有提供方法,坦率地说,这条错误消息没有用。这是我设法用谷歌搜索出的此错误的其他几个可能来源,但它们似乎并非如此:

  1. Scoping problems .
  2. Ambuiguity due to the same return type from different provision methods (即使我删除了提供 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;
    }
}

Activity 组件

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;
    }
}

下面是这些组件的使用方式。

申请

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

Activity

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

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

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)
    }
}

我错过了什么?

谢谢!

最佳答案

编辑

要点是:

如果您使用 dagger 的 @Subcomponent,请确保您在父级 @Component 中没有注入(inject)与您的子组件相同的目标类的方法.

Dagger 会感到困惑,并会尝试生成代码以直接从父组件注入(inject)到目标中,但它没有所需的模块来满足注入(inject)的依赖性。

关于android - Dagger 2 错误 : dependency “cannot be provided without an @Inject constructor” ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37225960/

相关文章:

android - 为什么 CameraX 不能在 Android Studio 中将图片放大到我需要的大小?

java - 使用 OkHttp/Retrofit 处理 Cookie - 无法解析符号 'Preferences'

通过将类作为函数参数传递来调用类方法的 Swift 依赖注入(inject)

angular - 在 Jasmine 单元测试中 : Can't resolve all parameters for TestFormInputComponentBase

Kotlin append 到文件

spring - @ManyToOne 的 "optional"参数是否使用 Kotlin 的可为空性自动设置

java - Unresolved 主机异常 Android

java - 将 ArrayList<Person> 传递给新 Activity

java - Guice Assisted : No implementation for java. lang.String 注释为 @com.google.inject.assisted.Assisted(value=prefix) 已绑定(bind)

android - 如何制作 Groupie recylerview 2x2 布局