Dagger2 compilation error in MVVM Factory when defining injector for fragment











up vote
0
down vote

favorite












I have a next root component:



@Singleton
@Component(modules = [AndroidInjectionModule::class,
AndroidSupportInjectionModule::class,
ActivityBuilderModule::class])
interface RootComponent : AndroidInjector<DaggerApplication> {
fun inject(myApplication: MyApplication)
override fun inject(photoPartyApplication: DaggerApplication)

@Component.Builder
interface Builder {
@BindsInstance
fun application(application: Application): Builder
fun build(): RootComponent
}
}


In ActivityBuilderModule:



@Module
abstract class ActivityBuilderModule {

@ContributesAndroidInjector(modules = [MainActivityModule::class,
ViewModelModule::class])
@ActivityScope
abstract fun bindMainActivity(): MainActivity

@ContributesAndroidInjector(modules = [SecondaryActivityModule::class,
ViewModelModule::class,
FragmentBuilderModule::class])
@ActivityScope
abstract fun bindSecondaryActivity(): SecondaryActivity

}


ViewModelModule is a trivial module to help making constructor injections in ViewModel classes and consists of @Binds between specific instances and ViewModel type.



MainActivityModule and SecondaryActivityModule define specific dependencies for corresponding activities.



The key thing is that when I added this FragmentBuilderModule - compilation started to emit errors. The stack trace is the next:




error: [Dagger/MissingBinding] some_package.SpecificDependency cannot be provided without an @Inject constructor or an @Provides-annotated method.



public abstract interface RootComponent extends dagger.android.AndroidInjector {



^



A binding with matching key exists in component: some_package.ActivityBuilderModule_BindMainActivity.MainActivitySubcomponent



some_package.SpecificDependency is injected at some_package.MainViewModel(specificDependency, …)



some_package.MainViewModel is injected at some_package.ViewModelModule.mainViewModel(viewModel)



Map<Class<? extends ViewModel>, Provider<ViewModel>> is injected at
some_package.ViewModelFactory(viewModelProviders)


some_package.ViewModelFactory is injected at some_package.ViewModelModule.bindViewModelFactory(factory)



android.arch.lifecycle.ViewModelProvider.Factory is injected at some_package.MyFragment.viewModelFactory



some_package.MyFragment is injected at dagger.android.AndroidInjector.inject(T)



[some_package.RootComponent → some_package.ActivityBuilderModule_BindSecondaryActivity.SecondaryActivitySubcomponent → some_package.FragmentBuilderModule_ProvideMyFragmentFactoryMyFragmentSubcomponent]




As far as I can understand, Dagger assumes that the whole dependencies graph has to be properly constructed for the map of Class<? extends ViewModel> -> Provider<ViewModel>, and if some ViewModels fall into factory, and that factory is injected into a component, then if component will ask for any viewmodel, it has to be delivered. And in order to deliver all the viewmodels, again, all the dependencies have to be available (what's not true, because specific dependency for the MainViewModel is available only from MainModule, and that's what dagger says before the stack trace).



Is there a workaround to provide dependencies to the map of Class<? extends ViewModel> -> Provider<ViewModel> on demand instead of building the whole graph at compile time (which is leading to the compile-time error)










share|improve this question




























    up vote
    0
    down vote

    favorite












    I have a next root component:



    @Singleton
    @Component(modules = [AndroidInjectionModule::class,
    AndroidSupportInjectionModule::class,
    ActivityBuilderModule::class])
    interface RootComponent : AndroidInjector<DaggerApplication> {
    fun inject(myApplication: MyApplication)
    override fun inject(photoPartyApplication: DaggerApplication)

    @Component.Builder
    interface Builder {
    @BindsInstance
    fun application(application: Application): Builder
    fun build(): RootComponent
    }
    }


    In ActivityBuilderModule:



    @Module
    abstract class ActivityBuilderModule {

    @ContributesAndroidInjector(modules = [MainActivityModule::class,
    ViewModelModule::class])
    @ActivityScope
    abstract fun bindMainActivity(): MainActivity

    @ContributesAndroidInjector(modules = [SecondaryActivityModule::class,
    ViewModelModule::class,
    FragmentBuilderModule::class])
    @ActivityScope
    abstract fun bindSecondaryActivity(): SecondaryActivity

    }


    ViewModelModule is a trivial module to help making constructor injections in ViewModel classes and consists of @Binds between specific instances and ViewModel type.



    MainActivityModule and SecondaryActivityModule define specific dependencies for corresponding activities.



    The key thing is that when I added this FragmentBuilderModule - compilation started to emit errors. The stack trace is the next:




    error: [Dagger/MissingBinding] some_package.SpecificDependency cannot be provided without an @Inject constructor or an @Provides-annotated method.



    public abstract interface RootComponent extends dagger.android.AndroidInjector {



    ^



    A binding with matching key exists in component: some_package.ActivityBuilderModule_BindMainActivity.MainActivitySubcomponent



    some_package.SpecificDependency is injected at some_package.MainViewModel(specificDependency, …)



    some_package.MainViewModel is injected at some_package.ViewModelModule.mainViewModel(viewModel)



    Map<Class<? extends ViewModel>, Provider<ViewModel>> is injected at
    some_package.ViewModelFactory(viewModelProviders)


    some_package.ViewModelFactory is injected at some_package.ViewModelModule.bindViewModelFactory(factory)



    android.arch.lifecycle.ViewModelProvider.Factory is injected at some_package.MyFragment.viewModelFactory



    some_package.MyFragment is injected at dagger.android.AndroidInjector.inject(T)



    [some_package.RootComponent → some_package.ActivityBuilderModule_BindSecondaryActivity.SecondaryActivitySubcomponent → some_package.FragmentBuilderModule_ProvideMyFragmentFactoryMyFragmentSubcomponent]




    As far as I can understand, Dagger assumes that the whole dependencies graph has to be properly constructed for the map of Class<? extends ViewModel> -> Provider<ViewModel>, and if some ViewModels fall into factory, and that factory is injected into a component, then if component will ask for any viewmodel, it has to be delivered. And in order to deliver all the viewmodels, again, all the dependencies have to be available (what's not true, because specific dependency for the MainViewModel is available only from MainModule, and that's what dagger says before the stack trace).



    Is there a workaround to provide dependencies to the map of Class<? extends ViewModel> -> Provider<ViewModel> on demand instead of building the whole graph at compile time (which is leading to the compile-time error)










    share|improve this question


























      up vote
      0
      down vote

      favorite









      up vote
      0
      down vote

      favorite











      I have a next root component:



      @Singleton
      @Component(modules = [AndroidInjectionModule::class,
      AndroidSupportInjectionModule::class,
      ActivityBuilderModule::class])
      interface RootComponent : AndroidInjector<DaggerApplication> {
      fun inject(myApplication: MyApplication)
      override fun inject(photoPartyApplication: DaggerApplication)

      @Component.Builder
      interface Builder {
      @BindsInstance
      fun application(application: Application): Builder
      fun build(): RootComponent
      }
      }


      In ActivityBuilderModule:



      @Module
      abstract class ActivityBuilderModule {

      @ContributesAndroidInjector(modules = [MainActivityModule::class,
      ViewModelModule::class])
      @ActivityScope
      abstract fun bindMainActivity(): MainActivity

      @ContributesAndroidInjector(modules = [SecondaryActivityModule::class,
      ViewModelModule::class,
      FragmentBuilderModule::class])
      @ActivityScope
      abstract fun bindSecondaryActivity(): SecondaryActivity

      }


      ViewModelModule is a trivial module to help making constructor injections in ViewModel classes and consists of @Binds between specific instances and ViewModel type.



      MainActivityModule and SecondaryActivityModule define specific dependencies for corresponding activities.



      The key thing is that when I added this FragmentBuilderModule - compilation started to emit errors. The stack trace is the next:




      error: [Dagger/MissingBinding] some_package.SpecificDependency cannot be provided without an @Inject constructor or an @Provides-annotated method.



      public abstract interface RootComponent extends dagger.android.AndroidInjector {



      ^



      A binding with matching key exists in component: some_package.ActivityBuilderModule_BindMainActivity.MainActivitySubcomponent



      some_package.SpecificDependency is injected at some_package.MainViewModel(specificDependency, …)



      some_package.MainViewModel is injected at some_package.ViewModelModule.mainViewModel(viewModel)



      Map<Class<? extends ViewModel>, Provider<ViewModel>> is injected at
      some_package.ViewModelFactory(viewModelProviders)


      some_package.ViewModelFactory is injected at some_package.ViewModelModule.bindViewModelFactory(factory)



      android.arch.lifecycle.ViewModelProvider.Factory is injected at some_package.MyFragment.viewModelFactory



      some_package.MyFragment is injected at dagger.android.AndroidInjector.inject(T)



      [some_package.RootComponent → some_package.ActivityBuilderModule_BindSecondaryActivity.SecondaryActivitySubcomponent → some_package.FragmentBuilderModule_ProvideMyFragmentFactoryMyFragmentSubcomponent]




      As far as I can understand, Dagger assumes that the whole dependencies graph has to be properly constructed for the map of Class<? extends ViewModel> -> Provider<ViewModel>, and if some ViewModels fall into factory, and that factory is injected into a component, then if component will ask for any viewmodel, it has to be delivered. And in order to deliver all the viewmodels, again, all the dependencies have to be available (what's not true, because specific dependency for the MainViewModel is available only from MainModule, and that's what dagger says before the stack trace).



      Is there a workaround to provide dependencies to the map of Class<? extends ViewModel> -> Provider<ViewModel> on demand instead of building the whole graph at compile time (which is leading to the compile-time error)










      share|improve this question















      I have a next root component:



      @Singleton
      @Component(modules = [AndroidInjectionModule::class,
      AndroidSupportInjectionModule::class,
      ActivityBuilderModule::class])
      interface RootComponent : AndroidInjector<DaggerApplication> {
      fun inject(myApplication: MyApplication)
      override fun inject(photoPartyApplication: DaggerApplication)

      @Component.Builder
      interface Builder {
      @BindsInstance
      fun application(application: Application): Builder
      fun build(): RootComponent
      }
      }


      In ActivityBuilderModule:



      @Module
      abstract class ActivityBuilderModule {

      @ContributesAndroidInjector(modules = [MainActivityModule::class,
      ViewModelModule::class])
      @ActivityScope
      abstract fun bindMainActivity(): MainActivity

      @ContributesAndroidInjector(modules = [SecondaryActivityModule::class,
      ViewModelModule::class,
      FragmentBuilderModule::class])
      @ActivityScope
      abstract fun bindSecondaryActivity(): SecondaryActivity

      }


      ViewModelModule is a trivial module to help making constructor injections in ViewModel classes and consists of @Binds between specific instances and ViewModel type.



      MainActivityModule and SecondaryActivityModule define specific dependencies for corresponding activities.



      The key thing is that when I added this FragmentBuilderModule - compilation started to emit errors. The stack trace is the next:




      error: [Dagger/MissingBinding] some_package.SpecificDependency cannot be provided without an @Inject constructor or an @Provides-annotated method.



      public abstract interface RootComponent extends dagger.android.AndroidInjector {



      ^



      A binding with matching key exists in component: some_package.ActivityBuilderModule_BindMainActivity.MainActivitySubcomponent



      some_package.SpecificDependency is injected at some_package.MainViewModel(specificDependency, …)



      some_package.MainViewModel is injected at some_package.ViewModelModule.mainViewModel(viewModel)



      Map<Class<? extends ViewModel>, Provider<ViewModel>> is injected at
      some_package.ViewModelFactory(viewModelProviders)


      some_package.ViewModelFactory is injected at some_package.ViewModelModule.bindViewModelFactory(factory)



      android.arch.lifecycle.ViewModelProvider.Factory is injected at some_package.MyFragment.viewModelFactory



      some_package.MyFragment is injected at dagger.android.AndroidInjector.inject(T)



      [some_package.RootComponent → some_package.ActivityBuilderModule_BindSecondaryActivity.SecondaryActivitySubcomponent → some_package.FragmentBuilderModule_ProvideMyFragmentFactoryMyFragmentSubcomponent]




      As far as I can understand, Dagger assumes that the whole dependencies graph has to be properly constructed for the map of Class<? extends ViewModel> -> Provider<ViewModel>, and if some ViewModels fall into factory, and that factory is injected into a component, then if component will ask for any viewmodel, it has to be delivered. And in order to deliver all the viewmodels, again, all the dependencies have to be available (what's not true, because specific dependency for the MainViewModel is available only from MainModule, and that's what dagger says before the stack trace).



      Is there a workaround to provide dependencies to the map of Class<? extends ViewModel> -> Provider<ViewModel> on demand instead of building the whole graph at compile time (which is leading to the compile-time error)







      android android-fragments dagger-2






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 19 at 17:10

























      asked Nov 19 at 16:26









      Andrey Ilyunin

      1,232220




      1,232220





























          active

          oldest

          votes











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53378877%2fdagger2-compilation-error-in-mvvm-factory-when-defining-injector-for-fragment%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown






























          active

          oldest

          votes













          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes
















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53378877%2fdagger2-compilation-error-in-mvvm-factory-when-defining-injector-for-fragment%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Costa Masnaga

          Fotorealismo

          Sidney Franklin