java - studio - Dagger 2: @ Component.Builder faltan configuradores para los módulos o componentes necesarios:[appi.example.com.dagger.AppModule] `
dagger android support (2)
Estoy configurando el nuevo módulo de Android Dagger pero recibí este error Aquí está mi componente:
@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 construyo así en mi aplicación
appComponent = DaggerAppComponent
.builder()
.application(this)
.appModule(new AppModule(this))
.netModule(new NetModule())
.build()
.inject(this);
Pero sigo recibiendo el error.
Error: (20, 3) error: @ Component.Builder faltan configuradores para los módulos o componentes necesarios: [app.example.com.dagger.AppModule]
Según la documentación que debería ser correcta, ¿qué me falta?
Por ejemplo, este podría ser un componente válido con un generador:
@Component(modules = {BackendModule.class, FrontendModule.class})
interface MyComponent {
MyWidget myWidget();
@Component.Builder
interface Builder {
MyComponent build();
Builder backendModule(BackendModule bm);
Builder frontendModule(FrontendModule fm);
}
}
Creo que esto proporciona una explicación algo más clara sobre el uso de @BindsInstance
y la eliminación de la @Provides Application
, Dagger 2 Component Builder :
@BindsInstance
¿Qué?Aquí está la definición:
Marca un método en un generador de componentes o en un generador de subcomponentes que permite vincular una instancia a algún tipo dentro del componente. - fuente
¿Qué pasa? Yo tampoco lo entiendo
Aquí hay un simple indicio de cuándo usarlo:
Los métodos de @BindsInstance deben preferirse a escribir un @Module con argumentos de constructor y proporcionar esos valores inmediatamente. - fuente
Vengo de Spring Boot y Dagger 2 es OMG mucho más complicado. :(
Entonces, basado en mi experiencia extremadamente limitada con Dagger 2, esto sucede porque hay un *Module
con un argumento de constructor que está mal configurado. Todavía no sé cómo configurar correctamente el Módulo con un argumento de constructor, pero prefiero seguir el enfoque recomendado dado por la documentación de Dagger 2, y eso es eliminar los argumentos del constructor y usar @BindsInstance
y @Inject
en @Inject
lugar.
p.ej
@Module
class NetModule { // no constructor argument here!
@Inject @Named("mqttServer") // replaced by @Inject
internal lateinit var mqttServer: String
}
y en 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)
}
Luego, proporciona las dependencias de los módulos al construir el DaggerAppComponent
desde la subclase de la Application
(asegúrese de especificar el nombre de la subclase en 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
}
}
Tenga en cuenta que el uso support-v4
Fragment
v support-v4
vs Fragment
nativo puede ser una fuente de problemas. por ejemplo, para support-v4, necesita usar HasSupportFragmentInjector
, HasSupportFragmentInjector
, mientras que con HasSupportFragmentInjector
, necesita usar AndroidInjectionModule
, HasFragmentInjector
.
Elimine el código a continuación de AppModule.class y reconstruya el proyecto
@Provides
@Singleton
Application provideContext(SomeApplication application) {
return application;
}