新しい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 __);
...
私のアプリケーションでこのように構築するもの
appComponent = DaggerAppComponent
.builder()
.application(this)
.appModule(new AppModule(this))
.netModule(new NetModule())
.build()
.inject(this);
しかし、私はまだエラーを受け取ります
エラー:(20、3)エラー:@ Component.Builderに必要なモジュールまたはコンポーネントのセッターがありません:[app.example.com.dagger.AppModule]
正しいはずのドキュメントによると、私は何が欠けていますか?
たとえば、これは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);
}
}
AppModule.classから以下のコードを削除し、プロジェクトを再構築します
@Provides
@Singleton
Application provideContext(SomeApplication application) {
return application;
}
これにより、@BindsInstance
の使用と@Provides Application
の削除、 Dagger 2 Component Builder の説明がやや明確になったと思います。
@BindsInstance
何?定義は次のとおりです。
インスタンスをコンポーネント内の特定のタイプにバインドできるようにするコンポーネントビルダーまたはサブコンポーネントビルダーのメソッドをマークします。 — source
なんだ?分かりませんか????
使用するタイミングの簡単なヒントを次に示します。
@BindsInstanceメソッドは、コンストラクター引数を使用して@Moduleを作成し、それらの値をすぐに提供するよりも優先する必要があります。 — source
私はSpring Bootから来ました。Dagger2はOMGがはるかに複雑です。 :(
したがって、Dagger 2での非常に限られた経験に基づいて、不適切に構成されたコンストラクター引数を持つ*Module
が存在するため、これが発生します。コンストラクター引数を使用してモジュールを適切に構成する方法はまだわかりませんが、Dagger 2のドキュメントで推奨されているアプローチに従います。コンストラクター引数を削除し、代わりに@BindsInstance
と@Inject
を使用します。
例えば.
@Module
class NetModule { // no constructor argument here!
@Inject @Named("mqttServer") // replaced by @Inject
internal lateinit var mqttServer: String
}
および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)
}
次に、DaggerAppComponent
サブクラスからApplication
を構築するときにモジュールの依存関係を指定します(必ず、 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
}
}
support-v4
Fragment
とネイティブFragment
の使用法が問題の原因になる可能性があることに注意してください。例えばsupport-v4の場合、AndroidSupportInjectionModule
、HasSupportFragmentInjector
を使用する必要がありますが、ネイティブでは、AndroidInjectionModule
、HasFragmentInjector
を使用する必要があります。
私の場合、オブジェクトモジュールを使用していたため、@ JvmStaticで注釈を付ける必要がありました