1

I've been trying to inject dependencies for my fragments using ContributesAndroidInjctor instead of creating a subcomponent but it throws an exception,

java.lang.IllegalArgumentException: No injector factory bound for Class<LoginFragment>

Here is what I'm trying to do,

Component:

@Component(
    dependencies = [LoginFeature.Dependencies::class],
    modules = [FeatureModule::class, AndroidInjectionModule::class]
)
interface LoginFeatureMainComponent : AndroidInjector<LoginFeatureImpl> {

    @Component.Factory
    interface Factory {
        fun create(
            @BindsInstance loginFeatureImpl: LoginFeatureImpl,
            loginFeature: LoginFeature.Dependencies
        ): LoginFeatureMainComponent
    }
}

Module:

@Module
abstract class FeatureModule {
    @ContributesAndroidInjector(modules = [ViewModelProviderModule::class])
    abstract fun contributeLoginFragment(): LoginFragment
}

Fragment:

class FragmentNew : DaggerFragment() {

    @Inject
    lateinit var viewModelProviderFactory: ViewModelProviderFactory
    private lateinit var binding: FragmentNewBinding
    private val newViewModel: NewViewModel by viewModels { viewModelProviderFactory }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? 
= DataBindingUtil.inflate<FragmentNewBinding>(inflater, R.layout.fragment_new, container, false).run {
        binding = this
        viewModel = newViewModel
        lifecycleOwner = viewLifecycleOwner
        root
    }
}

LoginFeatureImpl:

@AutoService(LoginFeature::class)
class LoginFeatureImpl : LoginFeature {
    override fun inject(dependencies: LoginFeature.Dependencies) {
            DaggerLoginFeatureMainComponent.factory().create(this, dependencies).apply {
                inject(this@LoginFeatureImpl)
            }
}
}

and my Activity basically calls inject method in LoginFeatureImpl:

class LaunchActivity : DaggerAppCompatActivity() {
    @Inject
    lateinit var viewModelProviderFactory: ViewModelProviderFactory
    private lateinit var binding: LaunchActivityBinding
    private val viewModel: LaunchViewModel by viewModels { viewModelProviderFactory }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this, R.layout.launch_activity)
        viewModel.launchLoginFragment() **// this calls inject in LoginFeatureImpl**
    }
}

any help regarding this issue is appreciated.

Edit: It works if I manually create a subcomponent instead of relying on ContributesAndroidInjector and calling inject in my fragment which implements HasAndroidInjector instead of extending from DaggerFragment(). But I'm still looking for a solution which uses ContributesAndroidInjector and not manually create Subcomponents for all the fragments that I add.

  • try using `AndroidSupportInjectionModule` and make sure that `DaggerFragment` uses `Fragment` from `androidx.fragment`, and not from `legacy-support-v4` – IR42 May 15 '20 at 18:22
  • @IR42 Just tried your suggestions, I made sure `DaggerFragment` was extending from `androidx.fragment` and I replaced `AndroidInjectionModule` with `AndroidSupportInjectionModule` in the component but I still get the same error `java.lang.IllegalArgumentException: No injector factory bound for Class` – Jitendra Reddy May 15 '20 at 18:43
  • This github issue from dagger has some nice solutions https://github.com/google/dagger/issues/1251 – denvercoder9 May 24 '20 at 21:11

0 Answers0