如何修复Dagger 2错误'...无法提供[...]'? [英] How do I fix Dagger 2 error '... cannot be provided [...]'?

查看:91
本文介绍了如何修复Dagger 2错误'...无法提供[...]'?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


这是规范问题,因为这是Dagger 2的常见错误。

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的依赖,但是当我发现时我收到以下错误尝试编译我的项目:

I tried to use a dependency with Dagger 2, but I receive the following error when I try to compile my project:


错误: com.example。 MyDependency 不能在没有@Inject构造函数的情况下提供,或者从@ Provide-annotated方法提供。

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

com.example。 MyDependency

com.example.MyComponent.myDependency()

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

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

What does this mean and how can I fix it?

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

I have a component and tried to provide a dependency. My basic setup looks like this:

// 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可以使用构造函数注入来提供对象,或者您需要在其中一个模块中使用某种方法创建或绑定对象。

tl;dr You forgot to either add an @Inject to your constructor so that Dagger can use Constructor Injection to provide the object, or you need some method in one of your Modules that creates or binds the object.

仔细查看错误消息:它表示您尝试请求依赖但 Dagger无法提供或创建。它根本不知道如何,因为如果没有@Inject构造函数或者@Project-annotated方法就不能提供

Have a good look at the error message: It states that you try to request a dependency but Dagger has no way to provide or create it. It simply does not know how to, because it cannot be provided without an @Inject constructor or from an @Provides-annotated method.

A仔细查看错误消息会显示您要提供的类(a)以及需要它的组件(b)

A close look at the error message shows the class (a) that you are trying to provide and the component (b) that needs it.


com.example.MyDependency (a)

com.example.MyComponent.myDependency()(b)

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

You have to make sure that (b) can create or provide (a) to fix your issue.

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

It looks a bit more complex if you tried to inject your dependency somewhere else, but you can still see the full stack of events—in this case a constructor injection missing a dependency. The class (a) that you are trying to provide and the location (b) where Dagger tried injecting it. It also tells you where that dependent class was created (c) and again the component (d) that failed providing (a).


com.example.MyDependency不能在没有@Inject构造函数或@Anvery-annotated方法的情况下提供。

com .example.MyDependency (a)

com.example.DependentClass注入。(依赖)(b)

com.example.DependentClass在(c)

com.example.MyComponent.myDependency()(d)

这同样适用:确保(d)知道如何提供(a)和你很高兴。

The same applies here: Make sure that (d) knows how to provide (a) and you're good to go.

看看错误是如上所示。确保您了解发生的位置以及您尝试注入的。然后告诉Dagger如何提供你的对象。

Have a look at the error as shown above. Make sure you understand where it occured and what you are trying to inject. Then tell Dagger how to provide your object.

如错误所述,你试试使用 MyDependency MyComponent 不知道如何操作。如果我们看一下这个例子,就会明白为什么:

As the error states, you try to use MyDependency but MyComponent does not know how to do that. If we have a look at the example it becomes clear why:

class MyDependency {}

该类有 @Inject 带注释的构造函数!组件中没有其他模块,因此Dagger无法做到。

The class has no @Inject annotated constructor! And there is no other module in the component, so there is nothing Dagger could do.

如果你想使用构造函数注入,你可以添加 @Inject 带注释的构造函数并完成。 Dagger会看到这个构造函数并知道如何创建你的类。

If you want to use constructor injection you can just add an @Inject annotated constructor and are done. Dagger will see this constructor and know how to create your class.

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

这就是你需要做的一切什么时候可以使用构造函数注入。

That is all you have to do when you can make use of constructor injection.

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

The error message states a second option, which allows you to provide an object if you don't want—or can't—use constructor injection. You can also add a @Provides annotated method to a module and add this module to your component.

@Module
class MyModule {
    @Provides
    MyDependency provideMyDependency() {
        return new MyDependency();
    }
}

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

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

This way Dagger can use your module to create and provide your dependency. It is a little bit more boilerplate than using Constructor Injection, but you will have to use Modules for everything that needs further setup or that does not have an annotated constructor, e.g. third party libraries like Retrofit, OkHttp, or Gson.

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

There are also other ways to provide a dependency from a component. A @SubComponent has access to its parents dependencies, and a component dependency can expose some of its dependencies to its dependent components. But at some point everything Dagger provides needs to either have an @Inject constructor or a Module providing it.

密切注意细节。你可能是当你只提供实现时使用接口,或者当Dagger只知道子类时尝试使用父类。

也许你添加了一个自定义 @Qualifier 或使用 @Named(typeA)。对匕首来说,这是一个完全不同的对象!仔细检查您实际提供并请求相同的依赖项。

Pay close attention to the details. You probably are using an interface when you are only providing the implementation, or try to use a parent class when Dagger only knows about the subclass.
Maybe you added a custom @Qualifier or used @Named("typeA") with it. To Dagger this is a completely different object! Double check that you actually provide and request the same dependency.

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

Read the error and make sure that you either have an @Inject annotated constructor, a module that has a @Provides method that provides that type, or a parent component that does.

如下所示的一个简单示例显示了一个类如何扩展另一个类:

A simple example like the following shows how one class extends another:

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

这将告知Dagger关于 MyDependency 但不是关于 MyBaseDependency

This will inform Dagger about MyDependency, but not about MyBaseDependency.

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

If you have one class implementing an interface or extending a super class you have to declare that. If you provide MyDependency this does not mean that Dagger can provide MyBaseDependency. You can use @Binds to tell Dagger about your implementation and provide it when the super class is required.

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

这篇关于如何修复Dagger 2错误'...无法提供[...]'?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆