Dagger2: Инъекция поля в ViewModel, которая имеет зависимости времени компиляции и времени выполнения - PullRequest
0 голосов
/ 24 декабря 2018

У меня есть список учеников, который отображается в RecyclerView, и для каждого ученика у меня есть StudentViewModel.Поскольку StudentViewModel нужен объект Student, который извлекается во время выполнения из базы данных, я не уверен, как я могу настроить внедрение конструктора для StudentViewModel, поэтому я не пытался использовать DI здесь.Тем не менее, теперь мне нужна другая зависимость в viewmodel, которая может быть разрешена во время компиляции и которая является моим NavUtil классом.

Мне удалось вставить его в мой StudentViewModel со следующими строками:

DaggerAppComponent.builder()
                .application(MyApp.INSTANCE)
                .build()
                .inject(this)

Но я не думаю, что это правильный путь, поскольку я ссылаюсь на класс Application из моей ViewModel просто ради DI.Я читал, что это возможно с помощью ViewModelFactory, но я не могу найти какой-либо убедительный пример или ссылку на это.Я уже использую его для ViewModels, которая имеет зависимости времени компиляции, но не в состоянии выяснить способ для ViewModel (s), который имеет зависимости времени компиляции и времени выполнения .Было бы здорово, если бы кто-то мог указать мне правильное направление.

Кстати, вот моя общая реализация DI:

Компонент приложения

@Component(modules = [AndroidInjectionModule::class, AndroidSupportInjectionModule::class,
    AppModule::class, AppProvider::class,StudentProvider::class])

@Singleton
interface AppComponent {

    @Component.Builder
    interface Builder {

        @BindsInstance
        fun application(application: Application): Builder

        fun build(): AppComponent
    }

    fun inject(app: MyApp)
    fun inject(studentViewModel: StudentViewModel)

StudentProvider

@Module
abstract class StudentProvider {

    @ContributesAndroidInjector(modules = [(ViewModelModule::class)])
    abstract fun bindHomeActivity(): HomeActivity
}

ViewModelModules

@Module
class ViewModelModule {

    @ActivityContext
    @Provides
    fun provideNavUtils(activity: Activity): NavUtil = NavUtil(activity)
}

StudentViewModel

class StudentViewModel(student: Student) : BaseViewModel() {

    @Inject
    lateinit var navUtils: NavUtil

    init {
        DaggerAppComponent.builder()
                .application(MyApp.INSTANCE)
                .build()
                .inject(this)
    }

    fun onSettingsTapped() {
        navUtils.navigateToSettings()
    }
}

NavUtil

class NavUtil @Inject constructor(@ActivityContext private val context: Context) {

    fun navigateToSettings() {
        context.startActivity(Intent(context, SettingsActivity::class.java))
    }
}

РЕДАКТИРОВАТЬ : похоже, что контекст действия не вводится, и вместо этого контекст приложения вводится.

...