web-dev-qa-db-fra.com

Dagger 2: @ Component.Builder manque des paramètres pour les modules ou composants requis: [appi.example.com.dagger.AppModule] `

Je configure le nouveau poignard Android mais j'ai eu cette erreur. Voici mon composant:

@AppScope
@Component(modules = {AppModule.class, NetModule.class})
public interface AppComponent {

  @Component.Builder
  interface Builder {
    @BindsInstance
    Builder application(ExampleApplication application);

    @BindsInstance
    Builder appModule(AppModule appModule);

    @BindsInstance
    Builder netModule(NetModule netModule);

    AppComponent build();
  }

  void inject(ExampleApplication __); 
...

Que je construis comme ça dans mon application

appComponent = DaggerAppComponent
      .builder()
      .application(this)
      .appModule(new AppModule(this))
      .netModule(new NetModule())
      .build()
      .inject(this);

Mais je reçois toujours l'erreur

Erreur: (20, 3) erreur: @ Component.Builder manque des paramètres pour les modules ou composants requis: [app.example.com.dagger.AppModule]

Selon la documentation qui devrait être exacte, qu'est-ce qui me manque?

Par exemple, cela pourrait être un composant valide avec un générateur:

@Component(modules = {BackendModule.class, FrontendModule.class})
interface MyComponent {
  MyWidget myWidget();

  @Component.Builder
  interface Builder {
    MyComponent build();
    Builder backendModule(BackendModule bm);
    Builder frontendModule(FrontendModule fm);
  }
}
37
Leonardo Deleon

Supprimez le code ci-dessous de AppModule.class et reconstruisez le projet.

    @Provides
    @Singleton
    Application provideContext(SomeApplication application) {
        return application;
    }
42
Gnanendra Kumar

Je pense que cela fournit une explication un peu plus claire sur l'utilisation de @BindsInstance et suppression de @Provides Application, Générateur de composants de poignard 2 :

@BindsInstance Quoi?

Voici la définition:

Marque une méthode sur un générateur de composant ou un générateur de sous-composant qui permet de lier une instance à un type quelconque du composant. - la source

QUOI? Je ne le comprends pas non plus ????

Voici un indice simple pour savoir quand l'utiliser:

Les méthodes @BindsInstance doivent être préférées à l'écriture d'un @Module avec des arguments de constructeur et à la fourniture immédiate de ces valeurs. - la source

Je viens de Spring Boot et Dagger 2 est OMG tellement plus compliqué. :(

Donc, basé sur mon expérience extrêmement limitée avec Dagger 2, cela se produit car il y a un *Module avec un argument constructeur mal configuré. Je ne sais toujours pas comment configurer correctement le module avec un argument de constructeur, mais je vais plutôt suivre l'approche recommandée dans la documentation de Dagger 2, à savoir supprimer le ou les arguments de constructeur et utiliser @BindsInstance et @Inject au lieu.

par exemple.

@Module
class NetModule { // no constructor argument here!

    @Inject @Named("mqttServer") // replaced by @Inject
    internal lateinit var mqttServer: String

}

et dans AppComponent:

@Singleton
@Component(modules = [AndroidSupportInjectionModule::class, AppModule::class, NetModule::class, ActivityBuilder::class])
interface AppComponent {

    @Component.Builder
    interface Builder {
        @BindsInstance
        fun application(application: Application): Builder

        @BindsInstance // you'll call this when setting up Dagger
        fun mqttServer(@Named("mqttServer") mqttServer: String): Builder

        fun build(): AppComponent
    }

    fun inject(app: GeoAssistantApp)
}

Ensuite, vous fournissez les dépendances des modules lors de la construction de DaggerAppComponent à partir de la sous-classe Application (assurez-vous que vous spécifiez le nom de la sous-classe dans AndroidManifest.xml ):

class GeoAssistantApp : Application(), HasActivityInjector, HasSupportFragmentInjector {

    @Inject
    internal lateinit var activityDispatchingAndroidInjector: DispatchingAndroidInjector<Activity>
    @Inject
    internal lateinit var fragmentDispatchingAndroidInjector: DispatchingAndroidInjector<Fragment>

    override fun onCreate() {
        super.onCreate()
        Log.i(GeoAssistantApp::class.Java.simpleName, "Initializing DaggerAppComponent...")
        DaggerAppComponent.builder()
                // list of modules/dependencies of modules that are part of this component need to be created here too
                .application(this)
                .mqttServer(getString(R.string.mqtt_server))
                .build()
                .inject(this)
    }

    override fun activityInjector(): AndroidInjector<Activity> {
        return activityDispatchingAndroidInjector
    }

    override fun supportFragmentInjector(): AndroidInjector<Fragment> {
        return fragmentDispatchingAndroidInjector
    }
}

Notez que le support-v4Fragment vs natif Fragment L'utilisation peut être une source de problèmes. par exemple. pour support-v4, vous devez utiliser AndroidSupportInjectionModule, HasSupportFragmentInjector, tandis qu'avec natif, vous devez utiliser AndroidInjectionModule, HasFragmentInjector.

14
Hendy Irawan

Dans mon cas, j'utilisais un objet module, alors je devais annoter avec @JvmStatic

7
Federico Torres