Dagger2 compilation error in MVVM Factory when defining injector for fragment












0















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





























    0















    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



























      0












      0








      0








      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 '18 at 17:10







      Andrey Ilyunin

















      asked Nov 19 '18 at 16:26









      Andrey IlyuninAndrey Ilyunin

      1,296220




      1,296220
























          1 Answer
          1






          active

          oldest

          votes


















          0















          First add ViewModelModule at RootComponent




           @Singleton
          @Component(modules = [AndroidInjectionModule::class,
          AndroidSupportInjectionModule::class,
          ActivityBuilderModule::class,
          ViewModelModule::class]) // add this so you don't have to add for every activity
          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
          }
          }



          Now in ActivityBuilderModule add only activty




           @Module
          abstract class ActivityBuilderModule {

          @ContributesAndroidInjector
          @ActivityScope
          abstract fun bindMainActivity(): MainActivity
          }



          Now In ViewModelModule add all ViewModel




           @Module
          abstract class ViewModelModule {

          @Binds
          @IntoMap
          @ViewModelKey(MainActivityModule::class)
          abstract fun bindMainActivityViewModel(mainActivityViewModel: MainActivityModule): ViewModel
          }



          Add ViewModelKey




           @MustBeDocumented
          @kotlin.annotation.Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
          @kotlin.annotation.Retention(AnnotationRetention.RUNTIME)
          @MapKey
          internal annotation class ViewModelKey(val value: KClass<out ViewModel>)



          And ViewModelFactory




          @Singleton
          class KotlinViewModelFactory @Inject
          constructor(private val creators: Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>) : ViewModelProvider.Factory {

          @Suppress("UNCHECKED_CAST")
          override fun <T : ViewModel> create(modelClass: Class<T>): T {
          var creator: Provider<out ViewModel>? = creators[modelClass]
          if (creator == null) {
          for ((key, value) in creators) {
          if (modelClass.isAssignableFrom(key)) {
          creator = value
          break
          }
          }
          }
          if (creator == null) {
          throw IllegalArgumentException("unknown model class $modelClass")
          }
          try {
          Timber.d(creator.toString())
          return creator.get() as T
          } catch (e: Exception) {
          throw RuntimeException(e)
          }
          }
          }





          share|improve this answer























            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',
            autoActivateHeartbeat: false,
            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

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            0















            First add ViewModelModule at RootComponent




             @Singleton
            @Component(modules = [AndroidInjectionModule::class,
            AndroidSupportInjectionModule::class,
            ActivityBuilderModule::class,
            ViewModelModule::class]) // add this so you don't have to add for every activity
            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
            }
            }



            Now in ActivityBuilderModule add only activty




             @Module
            abstract class ActivityBuilderModule {

            @ContributesAndroidInjector
            @ActivityScope
            abstract fun bindMainActivity(): MainActivity
            }



            Now In ViewModelModule add all ViewModel




             @Module
            abstract class ViewModelModule {

            @Binds
            @IntoMap
            @ViewModelKey(MainActivityModule::class)
            abstract fun bindMainActivityViewModel(mainActivityViewModel: MainActivityModule): ViewModel
            }



            Add ViewModelKey




             @MustBeDocumented
            @kotlin.annotation.Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
            @kotlin.annotation.Retention(AnnotationRetention.RUNTIME)
            @MapKey
            internal annotation class ViewModelKey(val value: KClass<out ViewModel>)



            And ViewModelFactory




            @Singleton
            class KotlinViewModelFactory @Inject
            constructor(private val creators: Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>) : ViewModelProvider.Factory {

            @Suppress("UNCHECKED_CAST")
            override fun <T : ViewModel> create(modelClass: Class<T>): T {
            var creator: Provider<out ViewModel>? = creators[modelClass]
            if (creator == null) {
            for ((key, value) in creators) {
            if (modelClass.isAssignableFrom(key)) {
            creator = value
            break
            }
            }
            }
            if (creator == null) {
            throw IllegalArgumentException("unknown model class $modelClass")
            }
            try {
            Timber.d(creator.toString())
            return creator.get() as T
            } catch (e: Exception) {
            throw RuntimeException(e)
            }
            }
            }





            share|improve this answer




























              0















              First add ViewModelModule at RootComponent




               @Singleton
              @Component(modules = [AndroidInjectionModule::class,
              AndroidSupportInjectionModule::class,
              ActivityBuilderModule::class,
              ViewModelModule::class]) // add this so you don't have to add for every activity
              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
              }
              }



              Now in ActivityBuilderModule add only activty




               @Module
              abstract class ActivityBuilderModule {

              @ContributesAndroidInjector
              @ActivityScope
              abstract fun bindMainActivity(): MainActivity
              }



              Now In ViewModelModule add all ViewModel




               @Module
              abstract class ViewModelModule {

              @Binds
              @IntoMap
              @ViewModelKey(MainActivityModule::class)
              abstract fun bindMainActivityViewModel(mainActivityViewModel: MainActivityModule): ViewModel
              }



              Add ViewModelKey




               @MustBeDocumented
              @kotlin.annotation.Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
              @kotlin.annotation.Retention(AnnotationRetention.RUNTIME)
              @MapKey
              internal annotation class ViewModelKey(val value: KClass<out ViewModel>)



              And ViewModelFactory




              @Singleton
              class KotlinViewModelFactory @Inject
              constructor(private val creators: Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>) : ViewModelProvider.Factory {

              @Suppress("UNCHECKED_CAST")
              override fun <T : ViewModel> create(modelClass: Class<T>): T {
              var creator: Provider<out ViewModel>? = creators[modelClass]
              if (creator == null) {
              for ((key, value) in creators) {
              if (modelClass.isAssignableFrom(key)) {
              creator = value
              break
              }
              }
              }
              if (creator == null) {
              throw IllegalArgumentException("unknown model class $modelClass")
              }
              try {
              Timber.d(creator.toString())
              return creator.get() as T
              } catch (e: Exception) {
              throw RuntimeException(e)
              }
              }
              }





              share|improve this answer


























                0












                0








                0








                First add ViewModelModule at RootComponent




                 @Singleton
                @Component(modules = [AndroidInjectionModule::class,
                AndroidSupportInjectionModule::class,
                ActivityBuilderModule::class,
                ViewModelModule::class]) // add this so you don't have to add for every activity
                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
                }
                }



                Now in ActivityBuilderModule add only activty




                 @Module
                abstract class ActivityBuilderModule {

                @ContributesAndroidInjector
                @ActivityScope
                abstract fun bindMainActivity(): MainActivity
                }



                Now In ViewModelModule add all ViewModel




                 @Module
                abstract class ViewModelModule {

                @Binds
                @IntoMap
                @ViewModelKey(MainActivityModule::class)
                abstract fun bindMainActivityViewModel(mainActivityViewModel: MainActivityModule): ViewModel
                }



                Add ViewModelKey




                 @MustBeDocumented
                @kotlin.annotation.Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
                @kotlin.annotation.Retention(AnnotationRetention.RUNTIME)
                @MapKey
                internal annotation class ViewModelKey(val value: KClass<out ViewModel>)



                And ViewModelFactory




                @Singleton
                class KotlinViewModelFactory @Inject
                constructor(private val creators: Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>) : ViewModelProvider.Factory {

                @Suppress("UNCHECKED_CAST")
                override fun <T : ViewModel> create(modelClass: Class<T>): T {
                var creator: Provider<out ViewModel>? = creators[modelClass]
                if (creator == null) {
                for ((key, value) in creators) {
                if (modelClass.isAssignableFrom(key)) {
                creator = value
                break
                }
                }
                }
                if (creator == null) {
                throw IllegalArgumentException("unknown model class $modelClass")
                }
                try {
                Timber.d(creator.toString())
                return creator.get() as T
                } catch (e: Exception) {
                throw RuntimeException(e)
                }
                }
                }





                share|improve this answer














                First add ViewModelModule at RootComponent




                 @Singleton
                @Component(modules = [AndroidInjectionModule::class,
                AndroidSupportInjectionModule::class,
                ActivityBuilderModule::class,
                ViewModelModule::class]) // add this so you don't have to add for every activity
                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
                }
                }



                Now in ActivityBuilderModule add only activty




                 @Module
                abstract class ActivityBuilderModule {

                @ContributesAndroidInjector
                @ActivityScope
                abstract fun bindMainActivity(): MainActivity
                }



                Now In ViewModelModule add all ViewModel




                 @Module
                abstract class ViewModelModule {

                @Binds
                @IntoMap
                @ViewModelKey(MainActivityModule::class)
                abstract fun bindMainActivityViewModel(mainActivityViewModel: MainActivityModule): ViewModel
                }



                Add ViewModelKey




                 @MustBeDocumented
                @kotlin.annotation.Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
                @kotlin.annotation.Retention(AnnotationRetention.RUNTIME)
                @MapKey
                internal annotation class ViewModelKey(val value: KClass<out ViewModel>)



                And ViewModelFactory




                @Singleton
                class KotlinViewModelFactory @Inject
                constructor(private val creators: Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>>) : ViewModelProvider.Factory {

                @Suppress("UNCHECKED_CAST")
                override fun <T : ViewModel> create(modelClass: Class<T>): T {
                var creator: Provider<out ViewModel>? = creators[modelClass]
                if (creator == null) {
                for ((key, value) in creators) {
                if (modelClass.isAssignableFrom(key)) {
                creator = value
                break
                }
                }
                }
                if (creator == null) {
                throw IllegalArgumentException("unknown model class $modelClass")
                }
                try {
                Timber.d(creator.toString())
                return creator.get() as T
                } catch (e: Exception) {
                throw RuntimeException(e)
                }
                }
                }






                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Dec 20 '18 at 4:44









                Shweta ChauhanShweta Chauhan

                2,23111629




                2,23111629






























                    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.




                    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

                    Guess what letter conforming each word

                    Port of Spain

                    Run scheduled task as local user group (not BUILTIN)