如何解决Dagger 2错误'…不能提供'?

这是一个典型问题,因为这是Dagger 2的常见错误。

如果你的问题被标记为重复,请仔细阅读这篇文章, 并确保明白这个错误的意思,为什么发生。 如果这篇文章不适合你,请确保包括 提供所提及的类的地方方式, 在你的问题中 包含完整的错误消息,如这里的一个。

我试图使用Dagger 2的依赖,但是当我尝试编译我的项目时收到以下错误:

错误: com.example。 没有@Inject构造函数或@提供注释的方法不能提供MyDependency

com。示例。 MyDependency提供在
com.example.MyComponent.myDependency()

这是什么意思,我该如何解决?

我有一个组件,并试图提供一个依赖。 我的基本设置如下所示:

// this is the dependency I try to use class MyDependency {} @Component interface MyComponent { // I want to make it accessible to be used with my component MyDependency myDependency(); } 

tl; dr您忘记了将@Inject添加到您的构造函数中,以便Dagger可以使用构造函数注入来提供该对象,或者您需要创build或绑定该对象的某个模块中的某个方法。


这是怎么回事?

仔细看看错误信息:它声明你试图请求依赖,但Dagger没有办法提供或创build它 。 它根本不知道如何去做,因为没有@Inject构造函数或@Proxy注解方法是不能提供的。

仔细查看错误消息,将显示您尝试提供的类(a)和需要它的组件(b)

com.example.MyDependency (a)提供在
com.example.MyComponent.myDependency() (b)

您必须确保(b)可以创build或提供(a)解决您的问题。

如果你尝试在别的地方注入你的依赖,看起来有点复杂,但你仍然可以看到完整的事件堆栈 – 在这种情况下,构造函数注入缺less依赖。 你试图提供的类(a)和匕首试图注入的位置(b) 。 它还告诉你在哪里创build了依赖类(c),以及(a)没有提供的组件(d

com.example.MyDependency不能提供没有@Inject构造函数或从@提供注释的方法。
com.example.MyDependency (a)注入
com.example.DependentClass。(依赖) (b)
(c)中提供了com.example.DependentClass,
com.example.MyComponent.myDependency() (d)

这同样适用于这里:确保(d)知道如何提供(a),并且你很好去。

我该如何解决?

看看上面的错误。 确保你了解它出现在哪里以及你想要注入什么 。 然后告诉Dagger如何提供你的对象。

一个@Inject构造函数

由于错误状态,您尝试使用MyDependencyMyComponent不知道如何做到这一点。 如果我们看一下这个例子,就会明白为什么:

 class MyDependency {} 

该类没有@Inject注释的构造函数 ! 而且组件中没有其他模块,所以Dagger没有什么可以做的。

如果你想使用构造函数注入,你可以添加一个@Inject注释的构造函数 ,并完成。 匕首将看到这个构造函数,并知道如何创build你的类。

 class MyDependency { @Inject MyDependency() { /**/ } } 

当你可以使用构造函数注入的时候,这就是你所要做的。

从@提供注释的方法

错误消息指出了第二个选项,如果您不想要或不能使用构造函数注入,则允许您提供一个对象。 您也可以将一个@Provides注释的方法添加到模块,并将此模块添加到您的组件。

 @Module class MyModule { @Provides MyDependency provideMyDependency() { return new MyDependency(); } } @Component(modules = MyModule.class) interface MyComponent { MyDependency myDependency(); } 

这样匕首可以使用你的模块来创build和提供你的依赖。 这比使用构造函数注入更有一些样板,但是对于需要进一步设置或没有注释构造函数的任何东西(例如Retrofit,OkHttp或Gson等第三方库),您都必须使用Modules。


还有其他的方式来提供组件的依赖。 一个@SubComponent可以访问父项的依赖项,而一个组件依赖项可以将它的一些依赖项暴露给它的依赖组件。 但是在某些时候,Dagger提供的一切都需要有一个@Inject构造函数或一个提供它的模块。

但是我添加了MyDependency

密切关注细节。 当你只提供实现的时候,你可能正在使用一个接口,或者当Dagger只知道子类的时候尝试使用一个父类。
也许你添加了一个自定义@Qualifier或使用@Named("typeA") 。 匕首这是一个完全不同的对象! 仔细检查,你实际提供和请求相同的依赖。

阅读错误,确保你有一个@Inject注释的构造函数,一个具有提供该types@Provides方法的模块,或一个具有这种types的父组件。

如果我想为我的界面提供一个实现呢?

下面这个简单的例子展示了一个类如何扩展另一个类:

 class MyDependency extends MyBaseDependency { @Inject MyDependency() { super(); } } 

这将告诉Dagger关于MyDependency但不关于MyBaseDependency

如果你有一个类实现一个接口或扩展一个超类,你必须声明。 如果你提供MyDependency这并不意味着Dagger可以提供MyBaseDependency 。 你可以使用@Binds来告诉Dagger你的实现,并在需要超类的时候提供。

 @Module interface MyModule { @Binds MyBaseDependency provideMyBaseDependency(MyDependency implementation); }