How to fix Dagger 2 error? ... cannot be provided [...] '?

This is a canonical question because it is a common mistake with dagger 2.

If your question has been marked as a duplicate, carefully read this message and make sure that he understands what this error means and why it occurred. If this message does not work, make sure that you indicate where and how you provide the mentioned classes, and include the full error message in your question, for example, here.

I tried using the dependency with Dagger 2, but when I try to compile my project, I get the following error:

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

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 am trying to provide dependency. My basic setup is as follows:

// 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(); } 
+8
source share
1 answer

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


What's happening?

Take a look at the error message: it indicates that you are trying to request a dependency, but the Dagger cannot provide or create it . He simply does not know how to do this, since it cannot be provided without the @Inject constructor or from the @ Provides-annotated method.

Look carefully at the error message: the class (a) that you are trying to provide and the component (b) that it needs.

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

You must ensure that (b) can create or provide (a) to fix your problem.

It looks a little more complicated if you tried to nest your dependency somewhere else, but you can still see the full stack of events - in this case, the installation of the constructor will not have a dependency. The class (a) you are trying to provide, and the location (b) where the Dagger tried to inject it. It also tells you where this dependent class (c) was created, and again component (d) , which did not provide (a) .. p>

com.example.MyDependency cannot be provided without the @Inject constructor or from the @ Provides-annotated method.
com.example.MyDependency (a) is entered in
com.example.DependentClass. (dependence) (b)
com.example.DependentClass is provided in (c)
com.example.MyComponent.myDependency () (d)

The same applies here: make sure (d) knows how to provide (a) , and you are good to go.

How to fix it?

Look at the error as shown above. Make sure you understand where this happened and what you are trying to enter. Then tell the Dagger how to secure your object.

constructor @Inject

As the error says, you are trying to use MyDependency , but MyComponent does not know how to do this. If we look at an example, it will become clear why:

 class MyDependency {} 

There is no annotated @Inject constructor in the @Inject ! And there is no other module in this component, so Dagger cannot do anything.

If you want to use the constructor installation, you can simply add the annotated @Inject and execute. The dagger will see this constructor and knows how to create its own class.

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

This is all you need to do when you can use constructor injection.

from method @ Provides an annotated method

The error message contains the second option, which allows you to provide an object if you do not want to use mdash or cannot use the constructor. You can also add @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(); } 

In this way, the Dagger can use your module to create and secure your addiction. This is a bit more than using the Injection constructor, but you will have to use modules for anything that needs further customization or that does not have an annotated constructor, for example. 3rd party libraries like Retrofit, OkHttp or Gson.


There are also other ways to ensure component dependency. A @SubComponent has access to the dependencies of its parents, and a component dependency can expose some of the dependencies on the dependent components. But at some point, all of Dagger provides either the @Inject constructor or the module that provides it.

But I added MyDependency !

Pay attention to the details. You are probably using the interface when you are only implementing, or trying to use the parent class when the Dagger knows only about the subclass.
You may have added a custom @Qualifier or used @Named("typeA") with it. For a dagger, this is a completely different object! Double check that you are indeed providing and requesting the same dependency.

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

What if I want to provide an implementation for my interface?

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

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

This will tell the Dagger about MyDependency , but not MyBaseDependency .

If you have one class that implements an interface or extends a superclass, you must declare it. If you provide MyDependency , this does not mean that the Dagger can provide MyBaseDependency . You can use @Binds to tell the dagger about your implementation and provide it when you need a superclass.

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

Source: https://habr.com/ru/post/1269490/


All Articles