java - ¿Cómo soluciono el error de Dagger 2 ''... no se puede proporcionar[...]''?
dagger-2 (1)
tl; dr
Olvidó agregar un
@Inject
a su constructor para que Dagger pueda usar la inyección de constructor para proporcionar el objeto, o necesita algún método en uno de sus módulos que cree o vincule el objeto.
¿Que esta pasando?
Observe el mensaje de error: indica que intenta solicitar una dependencia, pero Dagger no tiene forma de proporcionarla o crearla . Simplemente no sabe cómo hacerlo, porque no se puede proporcionar sin un constructor @Inject o desde un método anotado @ Provides.
Una mirada cercana al mensaje de error muestra la clase (a) que está tratando de proporcionar y el componente (b) que lo necesita.
com.example.MyDependency (a) se proporciona en
com.example.MyComponent.myDependency () (b)
Debe asegurarse de que (b) pueda crear o proporcionar (a) para solucionar su problema.
Parece un poco más complejo si intentas inyectar tu dependencia en otro lugar, pero aún puedes ver la pila completa de eventos, en este caso una inyección de constructor que falta una dependencia. La clase (a) que está tratando de proporcionar y la ubicación (b) donde Dagger intentó inyectarla. También le indica dónde se creó esa clase dependiente (c) y nuevamente el componente (d) que no proporcionó (a) .
com.example.MyDependency no se puede proporcionar sin un constructor @Inject o desde un método anotado @ Provides.
com.example.MyDependency (a) se inyecta en
com.example.DependentClass. (dependencia) (b)
com.example.DependentClass se proporciona en (c)
com.example.MyComponent.myDependency () (d)
Lo mismo se aplica aquí: asegúrese de que (d) sepa cómo proporcionar (a) y que esté listo para comenzar.
¿Cómo puedo solucionar esto?
Eche un vistazo al error como se muestra arriba. Asegúrese de comprender dónde ocurrió y qué está tratando de inyectar. Luego dígale a Dagger cómo proporcionar su objeto.
un constructor @Inject
Como indica el error, intenta utilizar
MyDependency
pero
MyComponent
no sabe cómo hacerlo.
Si echamos un vistazo al ejemplo, queda claro por qué:
class MyDependency {}
¡La clase
no
tiene
un constructor anotado
@Inject
!
Y no hay otro módulo en el componente, por lo que no hay nada que Dagger pueda hacer.
Si desea utilizar la inyección del constructor, simplemente puede
agregar un constructor anotado
@Inject
y listo.
Dagger verá este constructor y sabrá cómo crear su clase.
class MyDependency {
@Inject
MyDependency() { /**/ }
}
Eso es todo lo que tiene que hacer cuando puede utilizar la inyección del constructor.
desde un método anotado @ Provides
El mensaje de error establece una segunda opción, que le permite proporcionar un objeto si no quiere o no puede usar la inyección del constructor.
También puede
agregar un método anotado
@Provides
a un módulo y agregar este módulo a su componente.
@Module
class MyModule {
@Provides
MyDependency provideMyDependency() {
return new MyDependency();
}
}
@Component(modules = MyModule.class)
interface MyComponent {
MyDependency myDependency();
}
De esta manera, Dagger puede usar su módulo para crear y proporcionar su dependencia. Es un poco más repetitivo que usar Constructor Injection, pero tendrá que usar Módulos para todo lo que necesite una configuración adicional o que no tenga un constructor anotado, por ejemplo, bibliotecas de terceros como Retrofit, OkHttp o Gson.
También hay otras formas de proporcionar una dependencia de un componente.
Un
@SubComponent
tiene acceso a sus dependencias principales, y una dependencia de componente puede exponer algunas de sus dependencias a sus componentes dependientes.
Pero en algún momento todo lo que Dagger proporciona necesita tener un constructor
@Inject
o un Módulo que lo proporcione.
¡Pero sí
MyDependency
!
Presta mucha atención a los detalles.
Probablemente esté utilizando una interfaz cuando solo proporciona la implementación, o intente utilizar una clase principal cuando Dagger solo conozca la subclase.
Tal vez agregaste un
@Qualifier
personalizado o
@Qualifier
@Named("typeA")
con él.
¡Para Dagger, este es un objeto completamente diferente!
Verifique que realmente proporcione y solicite la misma dependencia.
Lea el error y asegúrese de tener un constructor anotado
@Inject
, un módulo que tenga un método
@Provides
que
proporcione ese tipo
o un componente padre que lo tenga.
¿Qué sucede si deseo proporcionar una implementación para mi interfaz?
Un ejemplo simple como el siguiente muestra cómo una clase extiende a otra:
class MyDependency extends MyBaseDependency {
@Inject MyDependency() { super(); }
}
Esto informará a Dagger sobre
MyDependency
,
pero no sobre
MyBaseDependency
.
Si tiene una clase que implementa una interfaz o extiende una superclase, debe declarar eso.
Si proporciona
MyDependency
esto no significa que Dagger pueda proporcionar
MyBaseDependency
.
Puede usar
@Binds
para informarle a Dagger sobre su implementación y proporcionarla cuando se requiera la
@Binds
.
@Module
interface MyModule {
@Binds
MyBaseDependency provideMyBaseDependency(MyDependency implementation);
}
Esta es una pregunta canónica porque es un error común con Dagger 2.
Si su pregunta se marcó como un duplicado , lea esta publicación detenidamente y asegúrese de comprender qué significa este error y por qué ocurrió. Si esta publicación no funciona para usted, asegúrese de incluir dónde y cómo proporciona las clases mencionadas e incluya el mensaje de error completo en su pregunta como la que se muestra aquí.
Intenté usar una dependencia con Dagger 2, pero recibo el siguiente error cuando intento compilar mi proyecto:
error: com.example. MyDependency no se puede proporcionar sin un constructor @Inject o desde un método anotado @ Provides.
com.ejemplo. MyDependency se proporciona en
com.example.MyComponent.myDependency ()
¿Qué significa esto y cómo puedo solucionarlo?
Tengo un componente e intenté proporcionar una dependencia. Mi configuración básica se ve así:
// 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();
}