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

时间:2016-05-14 11:16:32

标签: android dependency-injection kotlin dagger-2

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

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

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

    错误:没有提供com.example.ui.activity.MainActivity   @Inject构造函数或来自@ Provide-或@ Produces-annotated   方法

    1. 使用第二种方法,我得到所有依赖项的此错误。
    2. 知道我有提供方法,这个错误消息坦率地没用。以下是此错误的其他几个可能来源我已设法谷歌,但他们似乎并非如此:

      1. Scoping problems
      2. Ambuiguity due to the same return type from different provision methods(即使我删除提供Context的方法,问题仍然存在。)
      3. 以下代码在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;
            }
        }
        

        活动组件

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

        活动

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

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

        我错过了什么?

        谢谢!

1 个答案:

答案 0 :(得分:10)

修改

要点是:

如果您使用匕首bindec(decbin($number)) ,请确保您在父@Subcomponent中没有注入与子组件相同的目标类的方法。

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