title: Dagger 2 injecting view model of activity into fragment
body: <p>(using kotlin) I have an app that uses a settings activity with 2 fragments. I'd like both to get the same instance of the SettingsViewModel as the activity. I assume there's a scoping issue that I'm missing.</p>
  
  <p>First, I have the standard <code>ViewModelModule</code>:</p>
  
  <pre><code>@Module
  abstract class ViewModelModule {
      @Binds @IntoMap
      @ViewModelKey(SettingsViewModel::class)
      abstract fun bindSettingsViewModel(viewModel: SettingsViewModel): ViewModel
  
      @Binds
      abstract fun bindViewModelFactory(factory: MyViewModelFactory): ViewModelProvider.Factory
  }
  </code></pre>
  
  <p>I bind my activities in:</p>
  
  <pre><code>@Module
  abstract class AndroidBindingModule {
      @PerActivity
      @ContributesAndroidInjector(modules = [SettingsActivityModule::class])
      abstract fun contributeSettingsActivity(): SettingsActivity
  }
  </code></pre>
  
  <p>With all other things in place this works well and <code>SettingsActivity</code> does get an instance of the <code>SettingsViewModel</code>. <code>SettingsActivityModule</code> adds the following:</p>
  
  <pre><code>@PerFragment
  @ContributesAndroidInjector
  abstract fun contributeMainSettingsFragment(): MainSettingsFragment
  
  @PerFragment
  @ContributesAndroidInjector
  abstract fun contributeDebugSettingsFragment(): DebugSettingsFragment
  </code></pre>
  
  <p>Both fragments appear to have the injectors called on them (I've checked through the debugger and <code>AndroidSupportInjection.inject(fragment)</code> is called). The fragments include:</p>
  
  <pre><code>@Inject lateinit var mainViewModel: SettingsViewModel
  </code></pre>
  
  <p>But in my fragment's <code>onCreate()</code> I'm seeing that <code>mainViewModel</code> is still null. Is there anything special I need to do here to avoid calling <code>ViewModelProviders.of(activity)[SettingsViewModel::class.java]</code> and instead injecting the view model?</p>
  
  <p>UPDATE:</p>
  
  <p>After a bit more reading I found that the correct way of using the view model injection in fragments is to inject the factory and get the view model in <code>onActivityCreated</code>:</p>
  
  <pre><code>@Inject lateinit var viewModelFactory: ViewModelProvider.Factory
  lateinit var mainViewModel: SettingsViewModel
  
  override fun onActivityCreated(savedInstanceState: Bundle?) {
      super.onActivityCreated(savedInstanceState)
      mainViewModel = ViewModelProviders.of(activity, viewModelFactory)[SettingsViewModel::class.java]
  }
  </code></pre>
  
  <p>This makes sense since I have <code>MyViewModelFactory</code> bound as the <code>ViewModelProvider.Factory</code> and it's annotated with <code>@Singleton</code>. When I try to compile the above I get the following error:</p>
  
  <pre><code>Error:(6, 1) error: [dagger.android.AndroidInjector.inject(T)] java.util.Map&lt;kotlin.reflect.KClass&lt;? extends android.arch.lifecycle.ViewModel&gt;,? extends javax.inject.Provider&lt;android.arch.lifecycle.ViewModel&gt;&gt; cannot be provided without an @Provides-annotated method.
  </code></pre>
  
  <p>It appears that Dagger can't find the mapping created by the <code>ViewModelModule</code>. I'm still at a loss at how that can be. Maybe my tree is incorrect? Why would activities in <code>AndroidBindingModule</code> be able to get the ViewModel but not fragments?</p>
  
  <pre><code>AppComponent
    - AndroidInjectionModule
    - AndroidBindingModule
    - AppModule
      - SdkModule
      - ViewModelModule
      - GotItCardModule
      - ViewHolderSubcomponent (provides a mapping of layout ID -&gt; ViewHolder for a factory)
  </code></pre>
  
  <p>UPDATE</p>
  
  <p>I've done a little more digging into this... From the full error:</p>
  
  <pre><code>e: /home/user/workspace/Example/sdktest/build/tmp/kapt3/stubs/debug/com/example/sdktest/di/AppComponent.java:6: error: [dagger.android.AndroidInjector.inject(T)] java.util.Map&lt;kotlin.reflect.KClass&lt;? extends android.arch.lifecycle.ViewModel&gt;,? extends javax.inject.Provider&lt;android.arch.lifecycle.ViewModel&gt;&gt; cannot be provided without an @Provides-annotated method.
  e: 
  
  e: public abstract interface AppComponent {
  e:                 ^
  e:       java.util.Map&lt;kotlin.reflect.KClass&lt;? extends android.arch.lifecycle.ViewModel&gt;,? extends javax.inject.Provider&lt;android.arch.lifecycle.ViewModel&gt;&gt; is injected at
  e:           com.example.sdktest.di.viewmodel.ExampleViewModelFactory.&lt;init&gt;(creators)
  e:       com.example.sdktest.di.viewmodel.ExampleViewModelFactory is injected at
  e:           com.example.sdktest.di.viewmodel.ViewModelModule.bindViewModelFactory(factory)
  e:       android.arch.lifecycle.ViewModelProvider.Factory is injected at
  e:           com.example.sdktest.ui.settings.fragment.MainSettingsFragment.viewModelFactory
  e:       com.example.sdktest.ui.settings.fragment.MainSettingsFragment is injected at
  e:           dagger.android.AndroidInjector.inject(arg0)
  </code></pre>
  
  <p>I think the issue is that somehow Dagger is trying to inject my fragment with <code>dagger.android.AndroidInjecton</code> instead of <code>dagger.android.AndroidSupportInjection</code>. Still not sure how to fix.</p>