¿Cómo soluciono el error Dagger 2 ‘… no se puede proporcionar ‘?

Esta es una pregunta canónica porque este es un error común con Dagger 2.

Si su pregunta fue marcada como duplicada , lea esta publicación detenidamente y asegúrese de comprender qué significa este error y por qué ocurrió. Si esta publicación no funciona, asegúrese de incluir dónde y cómo proporciona las clases mencionadas e incluya el mensaje de error completo en su pregunta, como el que se encuentra aquí.

Traté de usar una dependencia con Dagger 2, pero recibo el siguiente error cuando bash comstackr mi proyecto:

error: com.example. MyDependency no se puede proporcionar sin un @Inject constructor o desde un @ Provides-método anotado.

com.example. 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(); } 

tl; dr Olvidaste agregar un @Inject a tu constructor para que Dagger pueda usar la Inyección de Constructor para proporcionar el objeto, o necesitas algún método en uno de tus Módulos que cree o vincule el objeto.


¿Que esta pasando?

Eche un vistazo al 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 @ Provides-anotado.

Una mirada cercana al mensaje de error muestra la clase (a) que está tratando de proporcionar y el componente (b) que la 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 stack completa de eventos, en este caso una inyección de constructor que no tiene una dependencia. La clase (a) que intentas proporcionar y la ubicación (b) donde Dagger intentó inyectarla. También le dice dónde se creó esa clase dependiente (c) y de nuevo el componente (d) que no proporcionó (a) .

com.example.MyDependency no se puede proporcionar sin un constructor @Inject o desde un método @ Provides-anotado.
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 aplica aquí: asegúrese de que (d) sepa cómo proporcionar (a) y que está listo para irse.

¿Cómo puedo solucionar esto?

Eche un vistazo al error como se muestra arriba. Asegúrese de comprender dónde ocurrió y qué está intentando inyectar. Luego dile a Dagger cómo proporcionar tu 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 Dagger no puede hacer nada.

Si desea utilizar la inyección de constructor, puede agregar un constructor @Inject anotado y listo. Dagger verá este constructor y sabrá cómo crear su clase.

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

Eso es todo lo que tienes que hacer cuando puedes utilizar la inyección de constructor.

de un método @ Provides-anotado

El mensaje de error indica una segunda opción, que le permite proporcionar un objeto si no desea, o no puede, utilizar la inyección del constructor. También puede agregar un método @Provides anotado 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 forma, Dagger puede usar su módulo para crear y proporcionar su dependencia. Es un poco más repetitivo que el uso de Constructor Injection, pero tendrá que usar los módulos para todo lo que necesite 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 las dependencias de sus padres, y una dependencia de los componentes 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 MyDependency !

Presta mucha atención a los detalles. Probablemente esté utilizando una interfaz cuando solo esté proporcionando la implementación, o intente utilizar una clase principal cuando Dagger solo conozca la subclase.
Quizás agregaste un @Qualifier personalizado o @Qualifier @Named("typeA") con él. ¡Para Dagger, este es un objeto completamente diferente! Verifique que realmente proporciona y solicita la misma dependencia.

Lea el error y asegúrese de tener un constructor @Inject anotado, un módulo que tenga un método @Provides que proporcione ese tipo , o un componente principal que sí lo haga.

¿Qué sucede si deseo proporcionar una implementación para mi interfaz?

Un ejemplo simple como el siguiente muestra cómo una clase amplí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 súper clase, debe declararla. Si proporciona MyDependency esto no significa que Dagger puede proporcionar MyBaseDependency . Puede usar @Binds para contarle a Dagger sobre su implementación y proporcionarla cuando se requiera la @Binds .

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