如何在 Dagger 刀柄中将 ViewModel 依赖项替换为调试变体并在 Jetpack compose 中使用它

How to replace ViewModel dependecy with debug variant in Dagger hilt and consume it in Jetpack compose

提问人:Samuel Robert 提问时间:10/18/2023 更新时间:10/19/2023 访问量:39

问:

我有一个 AuthViewModel,用于处理与用户身份验证相关的状态。

@HiltViewModel
open class AuthViewModel @Inject constructor(
    private val repo: AuthRepository,
    stateHandle: SavedStateHandle
) : ViewModel() {

    fun login() { ... }
    fun confirmLogin() { ... }
}

并在我的可组合项中使用它

@Composable
fun LoginScreen(vm: AuthViewModel = hiltViewModel(LocalContext.current as ComponentActivity)) {
    val state by vm.loginUiState.collectAsStateWithLifecycle()
    val credential by vm.credential.collectAsStateWithLifecycle()
    LoginUi(state, credential, vm::login)
}

为了使我们的测试更容易进行 QA,我从测试服务器实现了 OTP 的自动读取,并通过扩展它在 AuthViewModel 的源代码中实现了相同的功能。Debug

@HiltViewModel
class DebugAuthViewModel @Inject constructor(
    private val repo: DebugAuthRepository,
    stateHandle: SavedStateHandle
) : AuthViewModel(repo, stateHandle) {
    override fun login(mobile: String, onSuccess: () -> Unit) {
        super.login(mobile) {
            getOtp()
        }
    }

    private fun getOtp() {
        // fetch otp from repository
    }
}

现在,我希望将 AuthViewModel 替换为调试构建变体的 DebugAuthViewModel,这样我就不会在生产构建中提供此调试逻辑。

如何用 hilt 替换它,以便当我从可组合项中读取它时,我根据构建差异获得相应的 ViewModel?

我尝试创建一个限定符,如下所示:

@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class ViewModelQualifier(val value: String = BuildConfig.BUILD_TYPE)

并为伸展变体创建了 2 个刀柄模块

主要型号:

@Module
@InstallIn(SingletonComponent::class)
class AuthModule {
    @Provides
    @ViewModelQualifier("release")
    @ActivityScoped
    fun provideAuthViewModel(authViewModel: AuthViewModel): ViewModel {
        return authViewModel
    }
}

对于调试变体:

@Module
@InstallIn(SingletonComponent::class)
object DebugAuthModule {
    @ViewModelQualifier("debug")
    @Provides
    fun provideDebugAuthViewModel(debugAuthViewModel: DebugAuthViewModel): ViewModel {
        return debugAuthViewModel
    }
}

现在,我如何告诉或任何其他方法根据这些限定符返回正确的viewmodel实例?hiltViewModel()

android-jetpack-compose android-viewmodel dagger-hilt build-variant

评论


答:

0赞 Javad Jafari 10/19/2023 #1

有更简单的方法可以达到相同的结果。

  1. 如果您有发布和调试版本的生成变体,则可以在不同的源代码集中创建两个文件,并在搜索生成变体中使用正确的文件。
app
---- src
     ----- main
     ----- debug
           ------- xViewModel
     ----- release
           ------- xViewModel
  1. 您可以使用 BuildConfig 来确定应创建的 viewModel。

  2. 或者干脆在原始 viewModel 中添加那些额外的调试作品,并在其周围添加一个额外的 if 。

if (BuildConfig.BuildType == "debug") {
}

评论

0赞 Samuel Robert 10/20/2023
感谢您的输入。但是我将无法在调试变体的变体中继承ViewModel,因为源集不同。最重要的是,我不希望该语句确定我在生产代码中的依赖关系。因为我有一条严格的规则,我们不会向客户交付任何与调试相关的代码。releaseif
0赞 Javad Jafari 10/21/2023
@SamuelRobert如果你想使用继承,你可以把它和soruceSets混合使用。应该有两个 childViewModel,一个在发布源代码集中,另一个在调试中,发布一个是空的。调试具有额外的功能。