Dagger 2
/di/AppComponent.java:19: error: [Dagger/MissingBinding] ProductListFragment cannot be provided without an @Inject constructor or an @Provides-annotated method. This type supports members injection but cannot be implicitly provided.
public abstract interface AppComponent {
^
A binding with matching key exists in component: MainFragmentProvider_BindProductListFragment.ProductListFragmentSubcomponent
ProductListFragment is injected at
productlist.ProductListModule.provideChildFragmentManager(productListFragment)
androidx.fragment.app.FragmentManager is injected at
productlist.adapter.NewProductListPagerAdapter(…, fragmentManager)
productlist.adapter.NewProductListPagerAdapter is injected at
productlist.ProductListV2Fragment.mPagerAdapter
productlist.ProductListV2Fragment is injected at
dagger.android.AndroidInjector.inject(T) [di.AppComponent → di.BuilderModule_BindMainActivity.MainActivitySubcomponent → MainFragmentProvider_BindProductListV2Fragment.ProductListV2FragmentSubcomponent]
I have the following module with these 2 fragments here:
@Module
abstract class FragmentProvider {
@PerFragment
@ContributesAndroidInjector(modules = [ProductListModule::class])
abstract fun bindProductListV2Fragment(): ProductListV2Fragment
@PerFragment
@ContributesAndroidInjector(modules = [ProductListModule::class])
abstract fun bindProductListFragment(): ProductListFragment
}
In my ProductListModule I have the following:
@Module
class ProductListModule {
@Provides
fun provideChildFragmentManager(productListFragment: ProductListFragment) =
productListFragment.childFragmentManager
}
The fragmentManager will be injected into the following class:
class NewProductListPagerAdapter @Inject constructor(
@ActivityContext private val context: Context,
fragmentManager: FragmentManager
) { ..... }
And both fragments will inject this NewProductListPagerAdapter in them.
class ProductListV2Fragment : BaseProductListFragment() {
@Inject
lateinit var mPagerAdapter: NewProductListPagerAdapter
}
class ProductListFragment : BaseProductListFragment() {
@Inject
lateinit var mPagerAdapter: NewProductListPagerAdapter
}
My AppComponent:
@Singleton
@Component(
modules = [
AndroidSupportInjectionModule::class,
AppModule::class,
ProductModule::class,
BaseAppModule::class
]
)
interface AppComponent {
@Component.Factory
interface Factory {
fun create(
@BindsInstance application: Application,
): AppComponent
}
fun inject(tsApplication: TsApplication)
}
Your module depends on ProductListFragment
to obtain a child FragmentManager
. However, that same module is used to inject into ProductListV2Fragment
, and there is no ProductListFragment
available at that point.
In order to reuse that module, you will need to split the dependency on ProductListFragment
into a separate module. This module should be used for ProductListFragment
, and a similar module should be used for ProductListV2Fragment
. In these modules, you can either provide FragmentManager
directly or bind both fragments to a common superclass such as Fragment
or BaseProductListFragment
.
If you bind both fragments to Fragment
, the resulting code will look like this:
@Module
abstract class FragmentProvider {
@PerFragment
@ContributesAndroidInjector(modules = [
ProductListModule::class,
ProductListV2BindingModule::class
])
abstract fun bindProductListV2Fragment(): ProductListV2Fragment
@PerFragment
@ContributesAndroidInjector(modules = [
ProductListModule::class,
ProductListBindingModule::class
])
abstract fun bindProductListFragment(): ProductListFragment
}
@Module
class ProductListModule {
@Provides
fun provideChildFragmentManager(productListFragment: Fragment) =
productListFragment.childFragmentManager
}
@Module
abstract class ProductListBindingModule {
@Binds
fun bindFragment(fragment: ProductListFragment): Fragment
}
@Module
abstract class ProductListV2BindingModule {
@Binds
fun bindFragment(fragment: ProductListV2Fragment): Fragment
}
As for the error message itself, it tells you three things:
ProductListV2FragmentSubcomponent
requires a ProductListFragment
, but there is no available binding for it.ProductListFragment
. This can be useful information in other situations, but it isn't relevant to what you're trying to do.ProductListFragment
. Specifically, this is the generated ProductListFragmentSubcomponent
, which takes a ProductListFragment
in its factory.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.