support studio medium google compiler annotationprocessor java android dependency-injection dagger-2

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; }