如何解决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构造函数
由于错误状态,您尝试使用MyDependency
但MyComponent
不知道如何做到这一点。 如果我们看一下这个例子,就会明白为什么:
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); }