java - How do I fix Dagger 2 error '... cannot be provided [...]'? -
this canonical question because common error dagger 2.
if question flagged duplicate please read post and make sure understand error means , why occured. if post not work make sure include and how you provide mentioned classes , include the full error message in question 1 here.
i tried use dependency dagger 2, receive following error when try compile project:
error: com.example.mydependency cannot provided without @inject constructor or @provides-annotated method.
com.example.mydependency provided at
com.example.mycomponent.mydependency()
what mean , how can fix it?
i have component , tried provide dependency. basic setup looks this:
// dependency try use class mydependency {} @component interface mycomponent { // want make accessible used component mydependency mydependency(); }
tl;dr forgot either add @inject
constructor dagger can use constructor injection provide object, or need method in 1 of modules creates or binds object.
what's going on?
have @ error message: states try request dependency dagger has no way provide or create it. not know how to, because cannot provided without @inject constructor or @provides-annotated method.
a close @ error message shows class (a) trying provide , component (b) needs it.
com.example.mydependency (a) provided at
com.example.mycomponent.mydependency() (b)
you have make sure (b) can create or provide (a) fix issue.
it looks bit more complex if tried inject dependency somewhere else, can still see full stack of events—in case constructor injection missing dependency. class (a) trying provide , location (b) dagger tried injecting it. tells dependent class created (c) , again component (d) failed providing (a).
com.example.mydependency cannot provided without @inject constructor or @provides-annotated method.
com.example.mydependency (a) injected at
com.example.dependentclass.(dependency) (b)
com.example.dependentclass provided @ (c)
com.example.mycomponent.mydependency() (d)
the same applies here: make sure (d) knows how provide (a) , you're go.
how fix this?
have @ error shown above. make sure understand where occured , what trying inject. tell dagger how provide object.
an @inject constructor
as error states, try use mydependency
mycomponent
not know how that. if have @ example becomes clear why:
class mydependency {}
the class has no @inject
annotated constructor! , there no other module in component, there nothing dagger do.
if want use constructor injection can add @inject
annotated constructor , done. dagger see constructor , know how create class.
class mydependency { @inject mydependency() { /**/ } }
that have when can make use of constructor injection.
from @provides-annotated method
the error message states second option, allows provide object if don't want—or can't—use constructor injection. can add @provides
annotated method module , add module component.
@module class mymodule { @provides mydependency providemydependency() { return new mydependency(); } } @component(modules = mymodule.class) interface mycomponent { mydependency mydependency(); }
this way dagger can use module create , provide dependency. little bit more boilerplate using constructor injection, have use modules needs further setup or not have annotated constructor, e.g. third party libraries retrofit, okhttp, or gson.
there other ways provide dependency component. @subcomponent
has access parents dependencies, , component dependency can expose of dependencies dependent components. @ point dagger provides needs either have @inject
constructor or module providing it.
but did add mydependency
!
pay close attention details. using interface when providing implementation, or try use parent class when dagger knows subclass.
maybe added custom @qualifier
or used @named("typea")
it. dagger different object! double check provide , request same dependency.
read error , make sure either have @inject
annotated constructor, module has @provides
method provides type, or parent component does.
what if want provide implementation interface?
a simple example following shows how 1 class extends another:
class mydependency extends mybasedependency { @inject mydependency() { super(); } }
this inform dagger mydependency
, but not mybasedependency
.
if have 1 class implementing interface or extending super class have declare that. if provide mydependency
not mean dagger can provide mybasedependency
. can use @binds
tell dagger implementation , provide when super class required.
@module interface mymodule { @binds mybasedependency providemybasedependency(mydependency implementation); }
Comments
Post a Comment