草庐IT

java - 如何修复 Dagger 2 错误 '... cannot be provided [...]' ?

coder 2023-08-29 原文

This is a Canonical Question because this is a common error with Dagger 2.

If your question was flagged as a duplicate please read this post carefully and make sure to understand what this error means and why it occured. If this post does not work for you make sure to include where and how you provide the mentioned classes and include the full error message in your question like the one here.



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

error: com.example.MyDependency cannot be provided without an @Inject constructor or from an @Provides-annotated method.

com.example.MyDependency is provided at
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;博士 您忘记添加 @Inject到您的构造函数,以便 Dagger 可以使用构造函数注入(inject)来提供对象,或者您需要在您的模块之一中使用某种方法来创建或绑定(bind)对象。

这是怎么回事?

仔细查看错误消息:它指出您尝试请求依赖项,但 Dagger 无法提供或创建它 .它只是不知道怎么做,因为它不能在没有 @Inject 构造函数或从 @Provides-annotated 方法的情况下提供。

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

com.example.MyDependency (a) is provided at
com.example.MyComponent.myDependency() (b)



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

如果您尝试在其他地方注入(inject)依赖项,它看起来有点复杂,但您仍然可以看到完整的事件堆栈——在这种情况下,构造函数注入(inject)缺少依赖项。类(class) (a) 您尝试提供的信息和位置 (b) Dagger 尝试注入(inject)它的地方。它还告诉您该依赖类的创建位置 (c) 和组件 (d) 未能提供 (a) .

com.example.MyDependency cannot be provided without an @Inject constructor or from an @Provides-annotated method.
com.example.MyDependency (a) is injected at
com.example.DependentClass.(dependency) (b)
com.example.DependentClass is provided at (c)
com.example.MyComponent.myDependency() (d)



这同样适用于此处:确保 (d) 知道如何提供 (a) 你可以走了。

我该如何解决?

看看上面显示的错误。确保您了解它发生的位置以及您尝试注入(inject)的内容。然后告诉 Dagger 如何提供你的对象。

@Inject 构造函数

由于错误状态,您尝试使用 MyDependency但是 MyComponent不知道该怎么做。如果我们看一下这个例子,就会明白为什么:
class MyDependency {}

类(class)没有 @Inject带注释的构造函数!并且组件中没有其他模块,因此 Dagger 无能为力。

如果你想使用构造函数注入(inject),你可以只是 添加 @Inject带注释的构造函数 并完成。 Dagger 会看到这个构造函数并知道如何创建你的类。
class MyDependency {
    @Inject
    MyDependency() { /**/ }
}

当您可以使用构造函数注入(inject)时,这就是您所要做的全部。

来自@Provides 注释的方法

错误消息指出了第二个选项,它允许您在不想或不能使用构造函数注入(inject)时提供一个对象。您也可以添加 @Provides带注释的方法 到一个模块并将此模块添加到您的组件中。
@Module
class MyModule {
    @Provides
    MyDependency provideMyDependency() {
        return new MyDependency();
    }
}

@Component(modules = MyModule.class)
interface MyComponent {
    MyDependency myDependency();
}

这样 Dagger 就可以使用您的模块来创建和提供您的依赖项。它比使用构造函数注入(inject)要多一点样板,但是对于需要进一步设置或没有带注释的构造函数的所有内容,您必须使用模块,例如第三方库,如 Retrofit、OkHttp 或 Gson。

还有其他方法可以从组件提供依赖项。 @SubComponent可以访问其父依赖项,并且组件依赖项可以将其某些依赖项暴露给其依赖组件。但在某些时候,Dagger 提供的所有东西都需要有一个 @Inject构造函数或提供它的模块。

但我确实添加了 MyDependency !

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

阅读错误并确保您有 @Inject带注释的构造函数,一个具有 @Provides 的模块提供该类型的方法,或提供该类型的父组件。

如果我想为我的接口(interface)提供一个实现怎么办?

下面的一个简单示例显示了一个类如何扩展另一个类:
class MyDependency extends MyBaseDependency {
    @Inject MyDependency() { super(); }
}

这将通知 Dagger 关于 MyDependency , 但不是关于 MyBaseDependency .

如果你有一个类实现了一个接口(interface)或扩展了一个父类(super class),你必须声明它。如果您提供 MyDependency这并不意味着 Dagger 可以提供 MyBaseDependency .您可以使用 @Binds告诉 Dagger 关于你的实现并在需要父类(super class)时提供它。
@Module
interface MyModule {
    @Binds
    MyBaseDependency provideMyBaseDependency(MyDependency implementation);
}

关于java - 如何修复 Dagger 2 错误 '... cannot be provided [...]' ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44912080/

有关java - 如何修复 Dagger 2 错误 '... cannot be provided [...]' ?的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  4. ruby-on-rails - rails : "missing partial" when calling 'render' in RSpec test - 2

    我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou

  5. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  6. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  7. ruby-on-rails - Rails 常用字符串(用于通知和错误信息等) - 2

    大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje

  8. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  9. ruby - 如何指定 Rack 处理程序 - 2

    Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack

  10. ruby - 如何每月在 Heroku 运行一次 Scheduler 插件? - 2

    在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/

随机推荐