Java Dagger 2:@Component.Builder 缺少所需模块或组件的设置器:[appi.example.com.dagger.AppModule]`

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/44083243/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 01:18:37  来源:igfitidea点击:

Dagger 2: @Component.Builder is missing setters for required modules or components: [appi.example.com.dagger.AppModule]`

javaandroiddependency-injectiondagger-2

提问by Leonardo Deleon

I'm configuring the new Dagger Android module but I got this error Here's my Component:

我正在配置新的 Dagger Android 模块,但出现此错误 这是我的组件:

@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 __); 
...

Which I build like this in my Application

我在我的应用程序中像这样构建

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

But I still receive the error

但我仍然收到错误

Error:(20, 3) error: @Component.Builder is missing setters for required modules or components: [app.example.com.dagger.AppModule]

错误:(20, 3) 错误:@Component.Builder 缺少所需模块或组件的设置器:[app.example.com.dagger.AppModule]

According to the documentation that should be right, What am I missing?

根据应该正确的文档,我错过了什么?

For example, this could be a valid Component with a Builder:

例如,这可能是一个带有 Builder 的有效组件:

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

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

采纳答案by Gnanendra Kumar

Remove the below code from the AppModule.class and rebuild the project

从 AppModule.class 中删除以下代码并重建项目

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

回答by Hendy Irawan

I think this provides a somewhat clearer explanation on the use of @BindsInstanceand removal of @Provides Application, Dagger 2 Component Builder:

我认为这提供了使用的更为清楚的解释@BindsInstance和去除@Provides Application匕首2组件生成器

@BindsInstanceWhat?

Here's the definition :

Marks a method on a component builder or subcomponent builder that allows an instance to be bound to some type within the component.?—?source

WHAAT? I don't understand it either

Here's a simple hint of when to use it :

@BindsInstance methods should be preferred to writing a @Module with constructor arguments and immediately providing those values.?—?source

@BindsInstance什么?

这是定义:

在组件构建器或子组件构建器上标记一个方法,该方法允许将实例绑定到组件内的某种类型。?—?source

什么?我也不明白

这是何时使用它的简单提示:

@BindsInstance 方法应该优先于编写带有构造函数参数的 @Module 并立即提供这些值。?-?source

I come from Spring Boot and Dagger 2 is OMG so much more complicated. :(

我来自 Spring Boot,而 Dagger 2 是 OMG 复杂得多。:(

So based on my extremely limited experience with Dagger 2, this happens because there a *Modulewith a constructor argument which is improperly configured. I still don't know how to properly configure the Module with a constructor argument, but I rather follow recommended approach given by Dagger 2 documentation, and that is to remove the constructor argument(s) and use @BindsInstanceand @Injectinstead.

因此,根据我对 Dagger 2 极其有限的经验,发生这种情况是因为有*Module一个构造函数参数配置不正确。我仍然不知道如何使用构造函数参数正确配置模块,但我宁愿遵循 Dagger 2 文档给出的推荐方法,即删除构造函数参数并使用@BindsInstanceand@Inject代替。

e.g.

例如

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

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

}

and in AppComponent:

并在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)
}

Then you provide the dependencies of the modules when constructing the DaggerAppComponentfrom the Applicationsubclass (make sure you specify the subclass name in AndroidManifest.xml):

然后在DaggerAppComponentApplication子类构造 时提供模块的依赖项(确保在 中指定子类名称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
    }
}

Note that the support-v4Fragmentvs native Fragmentusage can be a source of problems. e.g. for support-v4, you need to use AndroidSupportInjectionModule, HasSupportFragmentInjector, while with native, you need to use AndroidInjectionModule, HasFragmentInjector.

请注意,support-v4Fragmentvs 本机Fragment使用可能是问题的根源。例如,对于 support-v4,您需要使用AndroidSupportInjectionModule, HasSupportFragmentInjector,而对于本机,您需要使用AndroidInjectionModule, HasFragmentInjector

回答by Federico Torres

In my case I was using an object Module, so I had to annotate provider method with @JvmStatic

在我的例子中,我使用的是一个对象模块,所以我不得不用 @JvmStatic 注释提供者方法

@Module
object GsonModule {

    @JvmStatic
    @Singleton
    @Provides
    fun provideGson() = Gson()

}